【问题标题】:Concrete class doesn't compile with a generic identifier具体类不使用通用标识符编译
【发布时间】:2018-09-19 09:07:41
【问题描述】:

我对这个编译错误感到困惑。考虑下面的代码sn-p,ConcreteClass1有如下编译错误:

错误:(16, 28) java: 不兼容的类型: java.util.Map java.lang.String,java.lang.String> 无法转换 到 java.util.Map java.lang.String,java.lang.Object>

然而ConcreteClass2 编译成功,仅仅是因为它扩展了AbstractClass 而不是AbstractClass<Object>。这是为什么呢?

abstract class AbstractClass<T extends Object> {

    void testGenerics(Map<String, Object> map) {
    }
}

class ConcreteClass1 extends AbstractClass<Object> {

    public void testGenerics() {
        Map<String, String> map = new HashMap<>();
        super.testGenerics(map);
    }
}

class ConcreteClass2 extends AbstractClass {

    public void testGenerics() {
        Map<String, String> map = new HashMap<>();
        super.testGenerics(map);
    }
}

【问题讨论】:

    标签: java generics language-lawyer


    【解决方案1】:

    ConcreteClass2 被声明为原始类型,因为省略了泛型信息。根据official Raw Types tutorial

    原始类型出现在遗留代码中,因为许多 API 类(例如 Collections 类)在 JDK 5.0 之前不是通用的。使用原始类型时,您基本上会获得预泛型行为

    因为上面的testGenerics(Map&lt;String, Object&gt; map)被解释为testGenerics(Map map),它可以被任何Map对象调用。这都是因为向后兼容 Java 5 之前的代码。

    你可以看看JLS 4.8 Raw Types

    【讨论】:

    • 啊,这就解释了!非常感谢。
    • “ConcreteClass2 被声明为原始类型”ConcreteClass2 不是原始类型。它只是一个非泛型类。但是,它继承原始类型 AbstractClass,这就是导致此行为的原因。
    【解决方案2】:

    这就是类型检查的美妙之处。 :)

    ConcreteClass2 扩展了一个原始的AbstractClass,因此没有编译时类型检查。但是编译器会警告您不要将原始类型用于参数化类。

    当使用原始类型时,构造函数、实例方法和非静态字段的类型也会被删除。

    【讨论】:

    • 你的意思是对ConcreteClass2中的所有代码都禁用了检查?
    • @DakshinamurthyKarra 不,它仅在涉及原始超类AbstractClass 的继承成员时才被禁用。 ConcreteClass2 中的其他通用代码仍在检查中。另一方面,ConcreteClass2 之外的代码如果访问这些成员,也会受到影响。
    • 确实如此。使用原始 AbstractClass 将导致整个类的类型擦除,包括其构造函数、实例方法和非静态字段。
    • 真的是警告吗?我看到Information:19/09/2018 09:57 - Compilation completed with 1 error and 0 warnings in 4 s 930 ms 和一条信息消息Information:java: ...\ConcreteClass2.java uses unchecked or unsafe operations.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-22
    • 1970-01-01
    • 2019-04-26
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    相关资源
    最近更新 更多