Why does using the cast
method on the Class<?>
Class produce an unchecked warning at compile time?
If you peek inside the cast method, you found this code :
public T cast(Object obj)
{
if (obj != null && !isInstance(obj))
throw new ClassCastException(cannotCastMsg(obj));
return (T) obj; // you can see there is a generic cast performed here
}
If i do a generic cast, the compiler complains saying that there is unchecked warning
.
You could find an example of how I arrived at this question inside the Book Effective Java 2 edition, page 166 (of the pdf).
The author writes this code
public <T> T getFavorite(Class<T> type)
{
return type.cast(favorites.get(type));
}
vs
public <T> T getFavorite(Class<T> type)
{
return (T) (favorites.get(type));
}
I just don't get the difference and why the compiler complains about the unchecked warning. In the end, both pieces of code do an explicit cast (T) object
, don't they?.
Without a @SuppressWarnings("unchecked")
annotation, the source code of java.lang.Class
would produce warnings during compilation. Warnings are not produced because the JDK classes are located in a library that is already compiled. I am sure compiling the JDK yourself would produce some warnings.
The comment by @Bohemian that this is an 'official kludge' is essentially correct and there are many examples of code like this. (Another example is java.lang.Enum#getDeclaringClass
.) It is safe to use because the logic as it is written is correct and it exists so you don't have to write this kind of ugly stuff yourself.
My advice is not to think too much about this implementation: what matters is that java.lang.Class#cast
conforms to the semantics of a checked cast.
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