The foo
method in following example gives us a warning, while bar
not?
public class X {
static class Y {}
static class Z extends Y {}
Y y = new Y();
<T extends Y> T foo() {
return (T) y; // warning - Unchecked cast from X.Y to T
}
Z bar() {
return (Z) y; // compiles fine
}
}
The type T is erased down to Y at compile time, this how generics work in Java. Thus when the cast is performed at run time the type of T is not available, it is just an Y
in the byte code.
bar()
compiles fine as all the type information is available (the cast will fail). But foo()
lacks this type information and cannot fail, potentially (or certainly, in this case) rendering the type signature of the method incorrect and becoming a source of bugs in the program.
To do this safely you need to pass the class itself to the method.
<T extends Y> T foo(Class<T> cls) {
return cls.cast(y); //No type warning. Will throw an error when cast fails.
}
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