tags:

views:

160

answers:

2

I have a generic type that is parameterized on some Enum, declared like this:

public class FlagsField<T extends Enum<T>> {

    private EnumSet<T> _flagSet;

    public FlagsField() {
        _flagSet = EnumSet.<T>noneOf( /* what goes here? */ );
    }

    ...
}

I want to initialize _flagsField in the constructor as above, but can't figure out for the life of me what the right parameter to the noneOf method is. It needs to be of type Class<T>. If this weren't a generic, you'd use MyFooEnumType.class here, but T.class is not valid.

Thanks!

+8  A: 

You've run into type erasure. Your constructor is going to need to look like:

public FlagsField(Class<T> enumClass) {
    _flagSet = EnumSet.<T>noneOf(enumClass);
}
Darron
Darron-- thank you. Can you explain why this is necessary?
quixoto
EnumSet needs to know about the type of the enum. For instance, complementOf will need to find all the enum constants of the type.
Tom Hawtin - tackline
Java compiles just one version of the code for your generic class; the code doesn't have any compile time knowledge of the type parameter.The JDK implementers faced this same issue; this is why EnumSet.noneOf() requires the class argument. You aren't going to be able to do better than they did.
Darron
I think the generic parameter is not necessary in the method call. `EnumSet.noneOf(enumClass)` would work.
Hosam Aly
+2  A: 

You could use this trick in your constructor: (see http://www.hibernate.org/328.html)

enumClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

But I believe this code only works when the class is sub-classed and an instance of the sub-class executes it.

Adrian Pronk