0

I'm trying to write a generic method for initializing an EnumSet value from an integer containing a bit mask. I'm getting a compiler error I don't understand. Here's my code:

   private <E extends Enum<E>> void setEnumSet( EnumSet<E> es, int iEnum ) {   
      es.clear(); 
      for (E e : E.values()) {   
         if (0 != (iEnum & (1<<e.ordinal()))) {
            es.add(e); 
         }
      }               
   }

Compiler error:

1>Javac...
1>.\wdqapi.java:266: error: cannot find symbol
1>      for (E e : E.values()) { 
1>                  ^
1>  symbol:   method values()
1>  location: class Enum<E>
1>  where E is a type-variable:
1>    E extends Enum<E> declared in method <E>_setEnumSet(EnumSet<E>,int)

Is there some special syntax for accessing the values() method of E? (I'm a Java noob.) Can someone help me past this compiler error? Thanks.

jbirkel
  • 27
  • 2

2 Answers2

4

You cannot do operations on generic types directly because at runtime type-erasure replaces all these with Object. Hence, the above code would be doing Object.values() which obviously doesn't work.

The way to do this is to use Class.getEnumConstants()

To do this you need an instance of E of the Class object of E. Again, remember that at runtime type-erasure will remove all references to the generic type.

Try something like:

private <E extends Enum<E>> void setEnumSet(E[] values,
      EnumSet<E> es, int iEnum )

or

private <E extends Enum<E>> void setEnumSet(Class<E> type, 
      EnumSet<E> es, int iEnum )
John B
  • 32,493
  • 6
  • 77
  • 98
  • Thanks, John. I went with passing-in the values array. Seems redundant but it gets the job done. Again, tyvm -- especially for timeliness! :) – jbirkel Mar 05 '13 at 18:34
0

As an alternative to passing in the values array, you can recover the Class<E> from the EnumSet. If the set isn't empty, use set.iterator().next().getDeclaringClass(); if the set is empty, use EnumSet.complementOf(set) to get a non-empty set, then get an element and get its class as before. (Strangely, EnumSet does not provide a method to get the enum class directly, despite having to store it for complementOf to work.)

Once you have the Class object, use Class.getEnumConstants as mentioned in John B's answer.

Jeffrey Bosboom
  • 13,313
  • 16
  • 79
  • 92