Java泛型错误?

Mic*_*ian 11 java generics

让我们有以下类层次结构:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么在overriden方法中存在编译错误MySubclass?错误消息是"类型不匹配:无法从对象转换为字符串".

有趣的是,如果我MySuperclassMySubclass定义中定义泛型类类型,则编译错误消失了:

public class MySubclass extends MySuperclass<MyType> {
    @Override
    protected String myMethod(String s) {
        return myMap.get(s);
    }
}
Run Code Online (Sandbox Code Playgroud)

有人可以解释这种行为吗?我认为这是一个Java编译器错误.

我正在使用jdk1.6.0_24.

mic*_*667 12

这不是一个bug.通过扩展MySuperclass而不是MySuperclass<MyType>,你扩展原始类型 MySuperclass,这意味着它myMap也将是类型Map而不是Map<String, String>.

  • @Thilo:请记住,仅存在原始类型****以实现向后兼容性.**如果**使用原始类型,则编译器会假定您的代码对于泛型有**.这对于能够使用泛型增强现有库而不破坏旧的非泛型代码是必要的. (11认同)
  • @miso [JLS](http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#110257)详细解释了它 (5认同)
  • 是的,这很奇怪.但这就是Java的工作方式 - 原始类型完全是原始的. (3认同)
  • 确切地。那是布洛赫的“谜题”之一。 (2认同)
  • 但是`MySuperclass**<MyType>**`的泛型定义与`Map**<String,String>**myMap`的泛型有什么共同之处?这是两种不同的泛型定义,它们之间没有"连接".我不明白. (2认同)