Re: Generic type cast involving wildcard type
On Jul 28, 4: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?
Casting is a runtime operation. By run time, all generics information
has been erased, so an attempt to do a generics-aware cast will yield
an "unchecked" warning. This is true for all generic casts except
those involving an unbound wildcard.
Part of the rationale is that such casts cannot be proven safe at
compile time.
A workaround is to use '@SuppressWarnings( "unchecked" )' at the
declaration of
'Derived<? extends CharSequence> derived'.
This annotation must be used most carefully only in places where you
can demonstrate conclusively that it's safe to do so, and you should
document that demonstration in a comment at the point of annotation.
If you make a mistake, you will get a 'ClassCastException' at runtime,
just the sort of problem generics were designed to prevent.
A better solution would be to complete your type analysis so that the
downcast is not needed.
For details and background, see:
<http://java.sun.com/docs/books/tutorial/extra/generics/index.html>
<http://java.sun.com/docs/books/effective/generics.pdf>
--
Lew