I want to pass any enum value to method in utility class and get another enum value of same enum type. Something like this:
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;
}
}
Use of method getEnumAttribute()
:
// 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 warnings or errors and it works like a charm.
But when I clean and compile project from command line by Maven2, it fails with error on line where is getEnumAttribute
called:
$ mvn clean compile
....
[ERROR] /home/.... DataUploader.java:[173,53] inconvertible types
found : java.lang.Enum<capture#414 of ?>
required: .....DataUploader.EUploadMethod
I am using Sun JDK 1.6 in either 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 this code is compilable and functional in Eclipse, and compile fails in Maven which using as far as I know same javac compiler?
What's wrong with passing specific enums to generic Enum<?>
parameters?
Thanks,
Martin Schayna
Eclipse compiler and javac have some differences, especially when it comes to generics. It is believed that eclipse is correct, but that doesn't matter :)
Try
public static <T extends Enum<T>> Enum<T> getEnumAttribute(Element element, String name,
Enum<T> defaultValue) {
...
}
I don't know what version of Eclipse you are using but I think it is wrong here. My version reports the same error that you are seeing with Maven, which appears to be a genuine error.
The problem is that you have two wildcards ("?"
) in the signature of getEnumAttribute()
but there is no constraint (nor is it possible to create one) that forces them to be the same. So a client could pass in an enum of one type as the default value and get an enum of a different type in return.
You can eliminate the error in the calling code by replacing both wildcards with a named type parameter:
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 it's possible to eliminate the unchecked cast, because Enum<E>.getClass()
returns Class<Enum<?>>
so the compiler cannot tell what type of enum is contained in the enumConstants
array.
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