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 enum
s 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.
精彩评论