简体   繁体   中英

Enum with generic base class passed as contructor parameter

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
    }
}

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();
}

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 ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM