GitHors GitHors - 1 year ago 57
Java Question

How l can call values() method on generic type <E extends Enum<E>>?

public static <E extends Enum<E>> void example(E e){
e. //what should I put here to get result of values()?

I am trying to call the method
that returns the values of an Enum using this method with generic arguments.

How can I do that?

Answer Source

Enum doesn't have values(). This method is dynamically added later by compiler when we are creating enum YourEnum. So we can't invoke values() on reference of Enum type.

Possible solution is

E[] values = e.getDeclaringClass().getEnumConstants();

We should use getDeclaringClass() instead of getClass() here, since enum values can be implemented as anonymous classes like in case of TimeUnit

public enum TimeUnit {
     * Time unit representing one thousandth of a microsecond
        public long toNanos(long d)   { return d; }
        public long toMicros(long d)  { return d/(C1/C0); }
        public long toMillis(long d)  { return d/(C2/C0); }
        public long toSeconds(long d) { return d/(C3/C0); }
        public long toMinutes(long d) { return d/(C4/C0); }
        public long toHours(long d)   { return d/(C5/C0); }
        public long toDays(long d)    { return d/(C6/C0); }
        public long convert(long d, TimeUnit u) { return u.toNanos(d); }
        int excessNanos(long d, long m) { return (int)(d - (m*C2)); }

in which case

  • TimeUnit.NANOSECONDS.getClass() returns java.util.concurrent.TimeUnit$3 (which doesn't declare any enum elements)
  • TimeUnit.NANOSECONDS.getDeclaringClass() returns java.util.concurrent.TimeUnit (with contains all of enum values).

It will also save us some trouble with casting since

  • getDeclaringClass returns Class<E>
  • getClass() returns Class<? extends E>

so result type of

  • getDeclaringClass().getEnumConstants() is E[]
  • getClass().getEnumConstants() is ? extends Enum[].

which allows us to even use it in a way like:

for (E value : e.getDeclaringClass().getEnumConstants()){
    //handle value