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?
In the general case, a generic type could be both a supplier and a consumer of its type parameters, which means that the type we get by casting the type parameter (up or down) cannot be either a subtype or a supertype of the original: they are unrelated types that cannot be cast between, which is exactly why the Java ...
As mentioned previously, generics can eliminate the requirement for casting.
Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter's scope is limited to the method where it is declared. Static and non-static generic methods are allowed, as well as generic class constructors.
Yes you can do it.
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>
.
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