Java: specific enums and general parameters Enum <?>
I want to pass any enum value to the method in the utility class and get another enumeration value of the same enumeration type. Something like that:
public class XMLUtils { public static Enum<?> getEnumAttribute(Element element, String name, Enum<?> defaultValue) { if (element.hasAttribute(name)) { String valueName = element.getAttribute(name); // search for value for (Enum<?> value: defaultValue.getClass().getEnumConstants()) if (value.toString().equalsIgnoreCase(valueName)) return value; } // not found, return default value return defaultValue; } } Using the getEnumAttribute() method:
// simple enum public enum EUploadMethod { INSERT, UPDATE, DELETE } // read enum value from XML config file EUploadMethod method = XMLUtils.getEnumAttribute(element, "method", EUploadMethod.INSERT); This code is fully functional, Eclipse compiles and runs it without warning or error, and it works like a charm.
But when I clean and compile the project from the command line using Maven2, it fails with an error in the line called getEnumAttribute :
$ mvn clean compile .... [ERROR] /home/.... DataUploader.java:[173,53] inconvertible types found : java.lang.Enum<capture#414 of ?> required: .....DataUploader.EUploadMethod I use Sun JDK 1.6 in Eclipse and Maven:
$ mvn -version Apache Maven 2.2.1 (r801777; 2009-08-06 21:16:01+0200) Java version: 1.6.0_14 Java home: /usr/lib/jvm/java-6-sun-1.6.0.14/jre Default locale: en_US, platform encoding: UTF-8 OS name: "linux" version: "2.6.27-17-generic" arch: "i386" Family: "unix" Questions:
Why is this code compiled and works in Eclipse , and compilation fails in Maven , which uses, as far as I know, the same javac compiler?
What is wrong with passing certain enumerations to the general parameters of
Enum<?>?
Thanks,
Martin Shayna
There are some differences between the Eclipse compiler and javac, especially when it comes to generics. It is believed that the eclipse is correct, but it does not matter :)
Try
public static <T extends Enum<T>> Enum<T> getEnumAttribute(Element element, String name, Enum<T> defaultValue) { ... }
I donβt know which version of Eclipse you are using, but I think it is wrong here. My version reports the same error you see with Maven, which seems like a genuine error.
The problem is that you have two wildcards ( "?" ) In the signature of getEnumAttribute() , but there is no restriction (and this is impossible to create), which makes them be the same. Thus, the client can pass an enumeration of one type as the default value and get another type in return.
You can resolve the error in the calling code by replacing both wildcards with a named parameter of the type:
class XMLUtils { @SuppressWarnings("unchecked") public static <E extends Enum<E>> E getEnumAttribute(Element element, String name, E defaultValue) { if (element.hasAttribute(name)) { String valueName = element.getAttribute(name); // search for value for (Enum<?> value: defaultValue.getClass().getEnumConstants()) if (value.toString().equalsIgnoreCase(valueName)) return (E) value; } // not found, return default value return defaultValue; } } But I donβt think that uncontrolled selection can be excluded because Enum<E>.getClass() returns Class<Enum<?>> , so the compiler cannot determine what type of enum is contained in the enumConstants array.