Let's have the following class hierarchy:
public class MyType {
}
public class MySuperclass<T extends MyType> {
protected Map<String, String> myMap = new TreeMap<String, String>();
protected String myMethod(String s) {
return myMap.get(s);
}
}
public class MySubclass extends MySuperclass {
@Override
protected String myMethod(String s) {
return myMap.get(s); // <-- compilation error
}
}
Why there is a compilation error in the overriden method of MySubclass
?
The error message is "Type mismatch: cannot convert from Object to String".
The interesting thing is that the compilation error dissapears if I define generics class type for MySuperclass
in MySubclass
definition:
public class MySubclass extends MySuperclass开发者_C百科<MyType> {
@Override
protected String myMethod(String s) {
return myMap.get(s);
}
}
Can somebody explain this behavior? I would consider it to be a Java compiler bug.
I'm using jdk1.6.0_24.
It is not a bug. By extending MySuperclass
instead of MySuperclass<MyType>
, you're extending the raw type MySuperclass
, which means that myMap
will also be of type Map
instead of Map<String, String>
.
It's indeed unreasonable. This can be considered a bug in design. The root cause is the decision to keep generified collection API backward compatible, instead of keeping the old one intact and introducing new generified API. This decision is technically nonsense, and their explanations are laughable. The real reason behind it is probably Sun was compelled to push out Java5 but didn't have enough resource, so they took the easy route (erasure). So here we are, totally screwed. This bastard type system not only is a problem in itself, it's also a great obstacle for introducing any new feature.
if Foo is a subtype (subclass or subinterface) of Bar, and G is some generic type declaration, it is not the case that G is a subtype of G.
You can refer http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf (for more information)
精彩评论