Re: Generic type cast involving wildcard type
On Jul 28, 10:49 pm, Daniel Thoma <dth...@gmx.net> wrote:
Hi!
I can't figure out, why casting to a subclass causes an unchecked cast
warning, when a wildcard type is involved, but seems to work in any other
case:
Example:
static class Base<T> { }
static class Derived<T> extends Base<T> { }
<T> void foo() {
Base<? extends CharSequence> base = new Derived<String>();
Derived<? extends CharSequence> derived
= (Derived<? extends CharSequence>) base; // causes war=
ning
Base<T> base2 = new Derived<T>();
Derived<T> derived2 = (Derived<T>) base2;
Base<String> base3 = new Derived<String>();
Derived<String> derived3 = (Derived<String>) base3;
}
Compiler warning:
warning: [unchecked] unchecked cast
found : test.Main.Base<capture#325 of ? extends java.lang.CharSequenc=
e>
required: test.Main.Derived<? extends java.lang.CharSequence>
Derived<? extends CharSequence> derived = (Derived<? ex=
tends CharSequence>)
base;
Is there an explanation for this behavior?
I believe the explanation lies in the correct interpretation of the ?
wildcard; I think I got struck by that too.
? extends X does not mean "any class that extends X", but "a given
class that extends X, which one I don't know".
So when you use <T> or <String> in your cast, the compiler knows
you're referring to the very same class; when you use <? extends
CharSequence>, the compiler understands that you're referring to two
classes that extend CharSequence, which might or might not be the same
one.
You cannot cast from List<T extends X> to List<S extends X>, and
using ? is just like using T or S, except that you don't name the
type.
--
Alessio