The problematic code is shown below.
class GenericClass<T> {
// ...
}
class RegisterHandler<T> {
// ...
public void register( Class<T> klazz ) {
// do something
}
// ...
}
class GenericClassRegisterHandler extends RegisterHandler<GenericClass<?>> {
// ...
}
public static void registerAll() {
// ...
new GenericClassRegisterHandler().register( GenericClass.class );
// error: actual argument Class<GenericClass> cannot be converted to Class<GenericClass<?>> by method invocation conversion
// ...
}
The only way was to use rawtypes, either by changing register
to Class klazz
instead of Class<T>
, or by casting new GenericClassRegisterHandler()
to (RegisterHandler)new GenericClassRegisterHandler()
. Since both of these "fixes" exploit rawtypes and I don't want to use them (why should I? I should be able to get Class<GenericClass<?>>
somehow by .class
!), yet I see no other solution so far. Am I missing something obvious and it's possible without reifying wrappers etc, or is it just impossible?
Note: Wrapping a Class<?> type generics error is a nice & enlightening find, but doesn't work here.
Note 2: While Bloch in EJ 2nd is discussing similar problems, I were unable to find any explicit solution to this exact case.
BTW the obvious (Class<GenericClass<?>>) GenericClass.class
doesn't work due to incompatible types: Class<GenericClass<?>> cannot be converted to Class<GenericClass>
Test snippet on http://ideone.com/Fr4yng
My solution was to do a double cast.
new GenericClassRegisterHandler()
.register( (Class<GenericClass<?>>) (Class<?>) GenericClass.class );
While it's arguably not the most elegant one, in some situations (e.g. you're the producer, and the consumer's interface is set in stone, or you just don't want to change it for any other reason) it's the best one - because it's the only one possible.