Say I have a class:
public class GClass implements GInterface<Impl> {
// other code
@Override
public Class<SomeClass> getType() {
return SomeClass.class
}
}
That implements generic interface:
public interface GInterface<T extends OtherClass> {
// other code
Class<SomeClass> getType();
}
And I then call getType():
GInterface gi = new GClass();
Class<SomeClass> type = gi.getType(); // <- gives warning
How does it make any sense that I get a warning here? The result of getType()
is not generic (it's not using the generic type parameter T) but statically defined as Class<SomeClass>
. Therefor the compiler should know that Class<SomeClass> type = gi.getType()
is 100% safe right?
Am I missing something?
I expected the call: Class<SomeClass> type = gi.getType()
to not generate any warnings.
UPDATE:
I now found out it has to do with the type parameter of gi
.
This generates warning (my question is why?):
GInterface gi = new GClass();
Class<SomeClass> type = gi.getType(); // <- gives warning
Doesnt give warning:
GInterface<?> gi = new GClass();
Class<SomeClass> type = gi.getType(); // <- Doesnt give warning
GInterface gi
is a raw type. The way Java works is that raw types basically put you into a "backwards compatibility mode" within the type checker, where the type works as if it did before generics were invented (that is, it's as if you're writing Java 1.4 code). In particular, the type's method signatures are completely stripped of generics in the compile-time calculations.
That means that with GInterface gi
, getType()
returns a raw Class
, not a Class<SomeClass>
. You're then assigning that raw type to a generic type, which is where the warning comes from.
(Note that this warning really is useful: because you're converting from a raw type to a generic type, the compiler has no way of checking that the conversion is correct. Class<FooBar> type = gi.getType()
would also compile, but wouldn't work as you expect at runtime.)
Declaring the type as GInterface<?> gi
means it's not a raw type anymore, so getType()
's compile-time type is the generic'ed Class<SomeClass>
.