我对此编译错误感到困惑。考虑下面的代码片段,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);
}
}
答案 0 :(得分:3)
ConcreteClass2
被声明为原始类型。根据{{3}}:
原始类型显示在旧版代码中,因为在JDK 5.0之前,许多API类(例如Collections类)不是通用的。使用原始类型时,您基本上会获得泛型行为
由于以上testGenerics(Map<String, Object> map)
被解释为testGenerics(Map map)
,因此可以与任何Map
对象一起调用。都是由于与Java 5之前的代码向后兼容。
答案 1 :(得分:2)
这就是类型检查的妙处。 :)
ConcreteClass2
扩展了原始AbstractClass
,因此没有编译时类型检查。但是,编译器会警告您不要对参数化类使用Raw类型。
使用原始类型时,构造函数,实例方法和非静态字段的类型也会被删除。