具体类未使用通用标识符进行编译

时间:2018-09-19 09:07:42

标签: java generics language-lawyer

我对此编译错误感到困惑。考虑下面的代码片段,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);
    }
}

2 个答案:

答案 0 :(得分:3)

由于省略了通用信息,因此

ConcreteClass2被声明为原始类型。根据{{​​3}}:

  

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

由于以上testGenerics(Map<String, Object> map)被解释为testGenerics(Map map),因此可以与任何Map对象一起调用。都是由于与Java 5之前的代码向后兼容。

您可以看看official Raw Types tutorial

答案 1 :(得分:2)

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

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

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