Call Enum. <T> valueOf (), issuing a warning without warning, even though T is declared <T extends Enum <T>>
It should be something small, but I do not understand.
Why does this raise a warning about an immediate cast compiler when it has the same general declaration as in Enum valueOf?
public static final <T extends Enum<T>> Enum toValue(T for_value, String value) {
try {
return Enum.<T>valueOf((Class<T>)for_value.getClass(), value);
} catch(RuntimeException rx) {
throw new IllegalArgumentException(value);
}
}
Compiler Warning:
R:\jeffy\programming\sandbox\xbnjava\xbn\util\EnumUtil.java:92:
warning: [unchecked] unchecked cast
Enum.<T>valueOf((Class<T>)for_value.getClass(), value);
^
required: Class<T>
found: Class<CAP#1>
where T is a type-variable:
T extends Enum<T> declared in method <T>toValue(T,String,String)
where CAP#1 is a fresh type-variable:
CAP#1 extends Enum from capture of ? extends Enum
R:\jeffy\programming\sandbox\xbnjava\xbn\util\EnumUtil.java:98: error: missing return statement
}
^
1 error
1 warning
This also happens in one or both generics removed from a function call, for example
Enum.valueOf(for_value.getClass(), value);
This is the closest question I found: Enum.valueOf issues a warning for an unknown class type that extends Enum? . This type of listing is known.
getClass, , Enum#valueOf. , getClass Class<? extends T>, Class<T>. , for_value T.
getClass a Class<?> Class<? extends T> :
Class<? extends |X|>...
, , X, . :
@SuppressWarnings("unchecked")
Class<? extends E> cls = (Class<? extends E>)for_value.getClass();
- Enum: , .
, Enum (E extends Enum<E>), , valueOf .
, - , Enum#getDeclaringClass.
JavaDocs toObject.getClass() indicate:
The actual type of result is the class where | X | is erasing the static type of the expression on which getClass is invoked.
The generic type erasureT is Object, therefore, for_value.getClass()has a return type Class<? extends Object>, not Class<T>. Trying to do this with help Class<T>is what gives you a warning without warning.