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<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 you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With