开发者

Using a supertype parameter of specific enum classes

开发者 https://www.devze.com 2023-02-07 13:41 出处:网络
I have two parser classes, and I want to throw an exception when parsing fails. I want to use the same exception, ParserException, which I\'d like could accept the field name which caused the failure.

I have two parser classes, and I want to throw an exception when parsing fails. I want to use the same exception, ParserException, which I'd like could accept the field name which caused the failure. I thought to use enums, but I think I don't have the topic completely clear.

How do I declare fieldName in the ParserException class? enum, as far as I understand, should be the supertype for ParserA.Fields and ParserB.Fields, but is not accepted.

Please note that the two enum classes contain a different set of enums, i.e. they are not the same class.

public class ParserA {

 public enum Fields {
  A_FIRST_FIELD
  A_SECOND_FIELD
 }


 public void parse() {
  ... 
 throw ParserException(Fields.A_FIRST_FIELD);  
 }

}

public class ParserB {

 public enum Fields {
  B_FIRST_FIELD
  B_SECOND_FIELD
 }

 public void parse() {
  ... 
  throw ParserException(Fields.B_FIRST_FIELD);  
 }

}



// Parser error
public class ParserException extends Exception {

 enum fieldName; // ????? what goes here?


 public ParserException(enum e) {
  this.fieldName = e;
 }

 public enum getFieldName() {  // ?????? how do I do something like this?
 开发者_开发知识库 return fieldName;
 }

}


Well, you could have ParserException store an Enum<?>, but this really doesn't provide you any real advantage over just using Object as the type for the field in ParserException.

Short of changing the design of what you're doing here, my preference would be to make a marker interface called Field and have all your enums that represent fields implement that... then ParserException could use Field as the type of object it stores.

public interface Field {
}

...

public enum Fields implements Field {
  A_FIRST_FIELD,
  A_SECOND_FIELD
}

...

public class ParserException extends Exception {
  private final Field field;

  public ParserException(Field field) {
    this.field = field;
  }

  public Field getField() {
    return field;
  }
}

For the most part, that something is an enum should be an implementation detail that nothing else should have to care about.


enum, as far as I understand, should be the supertype for ParserA.Fields and ParserB.Fields

Not enum, but Enum is the common supertype (or more precisely Enum<?>). But probably you don't want to use it, it's too general. It could be better to use something like

 // ParserExceptionKind is probably a better name
 public interface ParserEnum { 
      String name();
      // some useful methods go here
 }

 public class ParserA implements ParserEnum {
      public enum Fields {
           A_FIRST_FIELD
      }
 }

 public class ParserException extends Exception {
      private ParserEnum parserEnum;
      ...
 }

However, most of the time it's better to create separate subclasses of Exception.


Just use Fields type, like you would do with normal class.

Fields fieldName;

And similar in other cases.

BTW, enums are usually named in singular case (again, just like with classes, enums aren't that different).

edit
You can use Enum class (common superclass for all enums), or even Object.

But frankly, I see little point in declaring enum class with one element. You could've just used string constants: same functionality and less confusing.


ParserA.Fields and ParserB.Fields have no common super class, (except for the raw type Enum or Object, but I doubt that that's going to help you here).

Since enums can't be extended, I don't see how you would be able to solve this using enums.

You could work around this by changing enum into class and let both ParserA.Field and ParserB.Field extend ParserException.Field. In order to have the same advantages as enums however, you would have to limit the number of instances. There are several ways of achieving this, such as making the constructor protected, and have a limited number of public static members of this type.

0

精彩评论

暂无评论...
验证码 换一张
取 消