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.

+4
source share
3 answers

getDeclaringClass(), ( Class<T>). getClass() .

+8

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.

+1

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.

+1
source

Source: https://habr.com/ru/post/1537212/


All Articles