A co-worker ran into an interesting issue today, and while I think the actual, big-picture answer is "the fact that we're having this problem means we're doing something wrong", I figured I'd ask this anyway.
Given the following:
public class CrazyEnumTest {
public class EnumeratedThing<T extends Enum<T>> {
public T myValue;
public EnumeratedThing(T value) {
myValue = value;
}
}
public static void main (String[] args) {
String className = args[0];
String enumValue = args[1];
Enum<?> value1 = Enum.valueOf(Class.forName(className), enumValue);
EnumeratedThing<?> thing1 = new EnumeratedThing(value1);
}
}
I get the following compile error on the call to Enum.valueOf:
Bound mismatch: The generic method valueOf(Class<T>, String) of type Enum<E> is not applicable for the arguments (Class<capture#1-of ?>, String). The inferred type capture#1-of ? is not a valid substitute for the bounded parameter <T extends Enum<T>>
So, my question is: is it possible to, given only the String representation of a enumerated type name as well as the .name() of one of its values, get a reference to the corresponding enumerated type object as an Enum?
The compile error is telling you that Class<?>
is not the same as Class<? extends Enum>
. Try:
Enum<?> value1 =
Enum.valueOf((Class<? extends Enum>) Class.forName(className), enumValue);
Note that you'll get an unchecked cast warning, so make sure that className
actually does represent an enum. You could check by calling the isEnum()
method on the Class
object, like this:
Class<?> enumClass = Class.forName(className);
if (enumClass.isEnum()) {
@SuppressWarnings("unchecked") // we just checked it, so it had better work
Enum<?> value1 = Enum.valueOf((Class<? extends Enum>) enumClass, enumValue);
EnumeratedThing<?> thing1 = new EnumeratedThing(value1);
}
Of course, you'll get a raw type warning on "new EnumeratedThing(value1)
" anyway.
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