让我们有以下类层次结构:
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
}
}
为什么MySubclass
的overriden方法中存在编译错误?
错误消息是“类型不匹配:无法从对象转换为字符串”。
有趣的是,如果我在MySuperclass
定义中为MySubclass
定义泛型类类型,编译错误就会消失:
public class MySubclass extends MySuperclass<MyType> {
@Override
protected String myMethod(String s) {
return myMap.get(s);
}
}
有人可以解释这种行为吗?我认为这是一个Java编译器错误。
我正在使用jdk1.6.0_24。
答案 0 :(得分:12)
这不是一个错误。通过扩展MySuperclass
代替MySuperclass<MyType>
,您可以扩展原始类型 MySuperclass
,这意味着myMap
也将是Map
类型1}}而不是Map<String, String>
。
答案 1 :(得分:1)
这确实是不合理的。这可以被认为是设计中的错误。根本原因是决定保持通用集合API向后兼容,而不是保持原有集合API完整并引入新的通用API。这个决定在技术上是无稽之谈,他们的解释是可笑的。其背后的真正原因可能是Sun被迫推出Java5但没有足够的资源,所以他们采取了简单的路线(擦除)。所以我们完全搞砸了。这种混蛋型系统不仅本身就是一个问题,它也是引入任何新功能的一大障碍。
答案 2 :(得分:0)
如果Foo是Bar的子类型(子类或子接口),而G是一些 泛型类型声明,G不是G的子类型。
你可以参考 http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf(更多信息)