Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Generic method for Enums

Help me understand generics. Say I have two enums as inner classes like so:

public class FoodConstants {     public static enum Vegetable {         POTATO,BROCCOLI,SQUASH,CARROT;     }      public static enum Fruit {         APPLE,MANGO,BANANA,GUAVA;     } } 

Instead of having both enums implement an interface, and have to implement the same method twice, I would like to have a method in the outer class that does something like:

public <e> String getEnumString<Enum<?> e, String s) {     for(Enum en: e.values()) {         if(en.name().equalsIgnoreCase(s)) {             return s;         }     }     return null; } 

However this method does not compile. What I am trying to do is find out if a string value is the name of an enumerated value, in ANY enum, whether it's Vegetable, Fruit, what not. Regardless of whether this is in fact a redundant method, what is wrong with the one I am trying to (re)write?

Basically I would like to do this:

public class FoodConstants {     public static enum Vegetable {         POTATO,BROCCOLI,SQUASH,CARROT;     }      public static enum Fruit {         APPLE,MANGO,BANANA,GUAVA;     }      public <e> String getEnumString<Enum<?> e, String s) {         for(Enum en: e.values()) {             if(en.name().equalsIgnoreCase(s)) {                 return s;             }         }         return null;     } } //end of code 
like image 306
Alexander Mills Avatar asked May 06 '13 20:05

Alexander Mills


People also ask

Can enums be generic Java?

Java enums will be enhanced with generics support and with the ability to add methods to individual items, a new JEP shows. Since both features can be delivered with the same code change, they are bundled together in the same JEP. The change only affects the Java compiler, and therefore no runtime changes are needed.

Can enums be generic?

Unfortunately if you want to use an enum as a generic type, the obvious way of doing it doesn't work. enum is treated as a special type and Microsoft haven't implemented this (yet). However, it is possible to use enums in generics. The MSDN article for Enum gives the following type definition for the class Enum .

Can you use == for enums?

Because there is only one instance of each enum constant, it is permissible to use the == operator in place of the equals method when comparing two object references if it is known that at least one of them refers to an enum constant.

Can we mock enum in Java?

Extending the enum to add an extra value is not possible, and just mocking the equals method to return false won't work either because the bytecode generated uses a jump table behind the curtains to go to the proper case...


1 Answers

public static <E extends Enum<E>> String getEnumString(Class<E> clazz, String s){   for(E en : EnumSet.allOf(clazz)){     if(en.name().equalsIgnoreCase(s)){       return en.name();     }   }   return null; } 

The original has a few problems:

  1. It accepts an instance of the enum instead of the class representing the enum which your question suggests you want to use.
  2. The type parameter isn't used.
  3. It returns the input instead of the instance name. Maybe returning the instance would be more useful -- a case-insensitive version of Enum.valueOf(String).
  4. It calls a static method on an instance so you can iterate. EnumSet does all the reflective stuff for you.
like image 185
Mike Samuel Avatar answered Sep 22 '22 21:09

Mike Samuel