The following deserves no unchecked diagnostic, but javac produces one anyway.
interface A<T> {}
class B<T> {}
class C {
A<?> x = null;
B y = (B)x;
}
Another test case reported by the Eclipse team
import java.util.*;
public class X {
X(List rawList, List<?> unboundList) {
Throwable t0 = (Throwable) Collections.emptyList(); // unchecked
Throwable t1 = (Throwable) rawList; // no warn
Throwable t2 = (Throwable) unboundList; // unchecked
Object o = unboundList;
Throwable t3 = (Throwable) o; // no warn
}
}
Another test case clearly showing the silliness of the warning:
public class C {
interface I<T> {}
static void m(I<?> o) {
System.out.println("checking " + o);
System.out.println("[#1] instance of Exception? " + (o instanceof Exception));
System.out.println("[#2] instance of Exception? " + Exception.class.isInstance(o));
System.out.println("[#3] instance of Exception? " + ((I) o instanceof Exception));
}
public static void main(String[] x) {
class I1 implements I<String> {}
m(new I1());
class I2 extends Exception implements I<String> {}
m(new I2());
}
}
Though all three checks do the same thing, line #1 elicits an unchecked warning from the compiler. Note that checking 'o instanceof Cloneable' (an interface) results in no warning.