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
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.
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 .
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.
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...
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:
Enum.valueOf(String)
.EnumSet
does all the reflective stuff for you.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With