Unchecked cast warning when adding generic parameter

Viewed 214

The following Java code does NOT generate an unchecked cast warning (testing with Eclipse compiler for Java 8):

class Parent<T> {}

class Child<T> extends Parent<T> {}

class Test {
    <T> void test() {
        Parent<T> p = new Child<T>();
        // cast accepted by compiler:
        Child<T> cast = (Child<T>)p;
    }
}

So I understand the compiler must somehow have picked up that if p is both a Parent<T> (by compile-time type) and a Child (by run-time cast), then it is safe to assume it is a Child<T> as Child's passes its type parameter in its extends clause.

However the following similar code DOES generate an unchecked cast warning:

class Parent<T> {}

class Child<T, U> extends Parent<T> {}

class Test {
    <T, U> void test() {
        Parent<T> p = new Child<T, U>();
        // cast considered unsafe by compiler:
        Child<T, ?> cast = (Child<T, ?>)p;
    }
}

Yet the reasoning for considering the first example safe should also apply here! If p is a Parent<T> and a Child then it should be a Child<T, ?>, given Child's extends clause!

(Note that I do NOT include the U in the cast because that could indeed not checked, neither at compile-time or run-time.)

Is there any way to cast to a sub-type having additional parameters, without warnings?

1 Answers

As said in my comment those two cast work in Oracle's Java 1.8.0_112 compiler so presumably is a compiler error or limitation if you like.

I guess both cast should NOT be unsafe following the principle that assuming the Subclassing class is the correct one (i.e. the instance is indeed a Child) it must be true that it compatible with Child<T, ?> if it is a Parent<T>. In contrast it would not work (i.e. produce a warning) if you try to cast it to something like Child<U, V> where U is not guaranteed to be T or V is anything but ?, because there are Child's that are Parent<T> that are not necessarily Child<U, V>.

Related