问题 Java泛型错误?


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

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
    }
}

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

有趣的是,如果我为其定义泛型类类型,编译错误就会消失 MySuperclass 在 MySubclass 定义:

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

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

我正在使用jdk1.6.0_24。


8803
2017-10-14 11:59


起源



答案:


这不是一个bug。通过扩展 MySuperclass 代替 MySuperclass<MyType>,你正在扩展 原始类型  MySuperclass, 意思就是 myMap 也将是类型 Map 代替 Map<String, String>


12
2017-10-14 12:03



究竟。这是布洛赫的“益智游戏”之一。 - Bozho
但具有通用定义的是什么 MySuperclass**<MyType>** 与泛型的共同点 Map**<String, String>** myMap?这是两种不同的泛型定义,它们之间没有“连接”。我不明白。 - Michal Vician
@miso JLS 详细解释它 - michael667
是的,这很奇怪。但这就是Java的工作方式 - 原始类型完全是原始的。 - Dathan
@Thilo:请记住原始类型 只要 存在向后兼容性。 如果 您使用原始类型,然后编译器假定您的代码知道 没有 关于泛型。这是必要的,能够在不破坏旧的非通用代码的情况下使用泛型增强现有库。 - Joachim Sauer


答案:


这不是一个bug。通过扩展 MySuperclass 代替 MySuperclass<MyType>,你正在扩展 原始类型  MySuperclass, 意思就是 myMap 也将是类型 Map 代替 Map<String, String>


12
2017-10-14 12:03



究竟。这是布洛赫的“益智游戏”之一。 - Bozho
但具有通用定义的是什么 MySuperclass**<MyType>** 与泛型的共同点 Map**<String, String>** myMap?这是两种不同的泛型定义,它们之间没有“连接”。我不明白。 - Michal Vician
@miso JLS 详细解释它 - michael667
是的,这很奇怪。但这就是Java的工作方式 - 原始类型完全是原始的。 - Dathan
@Thilo:请记住原始类型 只要 存在向后兼容性。 如果 您使用原始类型,然后编译器假定您的代码知道 没有 关于泛型。这是必要的,能够在不破坏旧的非通用代码的情况下使用泛型增强现有库。 - Joachim Sauer


这确实是不合理的。这可以被认为是设计中的错误。根本原因是决定保持通用集合API向后兼容,而不是保持旧的集合API完整并引入新的通用API。这个决定在技术上是无稽之谈,他们的解释是可笑的。其背后的真正原因可能是Sun被迫推出Java5但没有足够的资源,所以他们采取了简单的路线(擦除)。所以我们完全搞砸了。这种混蛋型系统不仅本身就是一个问题,它也是引入任何新功能的一大障碍。


1
2017-10-14 21:58





如果Foo是Bar的子类型(子类或子接口),则G是一些 泛型类型声明,不是G是G的子类型的情况。

你可以参考 http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf (了解更多信息)


0
2017-10-14 12:26