I'm attempting to create an enum
whose constructor accepts an object whose base class is a generic class.
I seem to be unable to fetch the underlying generic type from within the enum
however, Object
gets returned instead of T
.
Is there a way to do this?
abstract public class Field<T> {
abstract public T get();
}
public class IntegerField extends Field<Integer> {
public Integer get() {
return 5;
}
}
public class StringField extends Field<String> {
public String get() {
return "5";
}
}
public enum Fields {
INTEGER (new IntegerField()),
STRING (new StringField());
private final Field<?> field; // <<--- I can't have Field<T>, enum's can't be generic. :(
<T> Fields(Field<T> field) {
this.field = field;
}
public <T> T get() {
return field.get(); // <<--- Returns Object, not T
}
}
CodePudding user response:
The issue is that enums can't be generically typed so even if you cast that get call ((T) field.get()
) you won't have type safety because it will agree with any assignment (you could compile this successfully for instance: boolean b = Fields.INTEGER.get()
).
Just use constants instead:
public final class Fields {
public static final Field<Integer> INTEGER = new IntegerField();
public static final Field<String> STRING = new StringField();
}
CodePudding user response:
Why do you think an enum is preferable to this?
public final class Fields {
public static final Field<Integer> INTEGER = new IntegerField();
public static final Field<String> STRING = new StringField();
//private ctor
}
or if you prefer
public final class Fields {
public static Field<Integer> integerField() {
return new IntegerField();
}
public static Field<String> stringField() {
return new StringField();
}
//private ctor
}
Why would I want to call Fields.INTEGER.get()
when I can just use Fields.INTEGER
?