This program does not compile:
public class xx {
static class Class1<C> {
void method1(C p) {
}
}
static class Class2<T> extends Class1<Class<? extends T>> {
T object;
void method2() {
this.method1(this.object.getClass());
}
}
}
The error is:
xx.java:10: method1(java.lang.Class<? extends T>) in xx.Class1<java.lang.Class<? extends T>>
cannot be applied to (java.lang.Class<capture#215 of ? extends java.lang.Object>)
this.method1(this.object.getClass());
Why does this happen? Why does the compiler seemingly believe that object.getClass() returns Class<? extends Object> instead of Class<? extends T> ?
Object.getClass()is defined to return aClass<? extends |T|>, whereTis the statically known type of the receiver (the objectgetClass()is called on). Take special note of the vertical bars, the erasure operator. The erasure of a type variable is the erasure of its leftmost bound. In your case that’s the implicit boundObject. So you get back aClass<? extends Object>, not aClass<? extends T>.Why is that?
Imagine
T = List<Integer>, you could suddenly do the following without unchecked warning:But thankfully we do get a warning.. 😉