简体   繁体   中英

Casting to generic subtypes of a generic class

Suppose I have this:

class Base<T> {}

class Derived<T> extends Base<T> {}

Then in my code, I can safely cast without a warning like this:

public <T> void foo(Base<T> base) {
    Derived<T> f = (Derived<T>) base; // fine, no warning
}

which is fine. But if the derived class has more type parameters, it doesn't work any more:

class Base<T> {}

class Derived<T, U> extends Base<T> {}

public <T> void foo(Base<T> base) {
    Derived<T, ?> f = (Derived<T, ?>) base; // unchecked warning!
}

Why is that? Is there something obvious I'm missing here?

This seems like a bug to me. From JLS §5.5.2. Checked Casts and Unchecked Casts :

A cast from a type S to a parameterized type (§4.5) T is unchecked unless at least one of the following conditions holds:

  • S <: T

  • All of the type arguments (§4.5.1) of T are unbounded wildcards

  • T <: S and S has no subtype X other than T where the type arguments of X are not contained in the type arguments of T.

Given your types Base<T> and Derived<T, ?> as S and T respectively, the first two conditions clearly don't hold.

That leaves the third condition - which won't hold if we can identify a subtype of Base<T> other than Derived<T, ?> whose type arguments are not contained in the type arguments of Derived<T, ?> . If the warning is correct, such a subtype must exist, but I can't identify one. For example, Derived<?, ?> doesn't work because it isn't a subtype of Base<T> .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM