Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generics inheritance warning

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
    }

}
like image 495
gudge Avatar asked Apr 28 '14 11:04

gudge


1 Answers

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.
}
like image 158
ggovan Avatar answered Oct 02 '22 20:10

ggovan