I would expect that from the aspect of compile time as well as from the aspect of runtime it wouldn't be a problem for .getClass()
to provide a correctly-typed return value.
But I must be wrong.
public class _GetClassGenerics2 {
static class MyClass {
}
public static void main(String[] args) {
MyClass myInstance = new MyClass();
// here it works
Class<? extends MyClass> type = myInstance.getClass();
myMethod(myInstance);
}
public static <T extends MyClass> void myMethod(T instance) {
Class<? extends T> type = instance.getClass();
// java.lang.RuntimeException: Uncompilable source code - incompatible types
// required: java.lang.Class<? extends T>
// found: java.lang.Class<capture#1 of ? extends _GetClassGenerics2.MyClass>
}
}
EDIT: It doesn't work with Class<T>
and Class<? super T>
either.
As per the Javadoc of the getClass
method:
The actual result type is
Class<? extends |X|>
where |X| is the erasure of the static type of the expression on whichgetClass
is called. For example, no cast is required in this code fragment
Here, the value for |X|
in your code snippet is MyClass
, hence instance.getClass()
is assignable to only Class<? extends MyClass>
or Class<?>
.
The reason for this specific wording is because when you say that for this variable having type T where <T extends MyClass>
, there can be multiple classes which extend MyClass
and hence capable of satisfying the T extends MyClass
criteria. Without runtime information there is no way of knowing which concrete implementation subclass of MyClass
was passed in the method. Hence to provide a generic solution, it returns <? extends MyClass>
since that would hold true for any subclass of MyClass
irrespective of what class instance is passed in.