给定以下接口(interface)和类:
public interface Interface<T> {
List<T> get(List<List<Object>> keys);
}
public class Cls implements Interface {
@Override
public List get(List<List<Object>> keys) {
return Collections.emptyList();
}
}
导致编译错误:
TypeTest.java:[9,11] error: Cls is not abstract and does not override abstract method get(List) in Interface TypeTest.java:[12,20] error: name clash: get(List<List<Object>>) in Cls and get(List<List<Object>>) in Interface have the same erasure, yet neither overrides the other
但这行得通:
public interface Interface<T> {
List<T> get();
}
public class Cls implements Interface {
@Override
public List get() {
return Collections.emptyList();
}
}
这样做:
public interface Interface<T> {
List<T> get(List<List<Object>> keys);
}
public class Cls implements Interface {
@Override
public List get(List keys) {
return Collections.emptyList();
}
}
我不明白这种行为。类型删除仅适用于类型参数 T
,不是吗?为什么会漏掉 T
影响不相关List<List<Object>> keys
参数?
最佳答案
由于原始类型发生类型删除,您在第一个示例中遇到编译器错误。 Section 4.8 of the JLS描述了使用原始类型会产生类型删除的情况:
To facilitate interfacing with non-generic legacy code, it is possible to use as a type the erasure (§4.6) of a parameterized type (§4.5) or the erasure of an array type (§10.1) whose element type is a parameterized type. Such a type is called a raw type.
和
The superclasses (respectively, superinterfaces) of a raw type are the erasures of the superclasses (superinterfaces) of any of its parameterized invocations.
本节中的其他条款还描述了字段类型、方法的返回类型和方法的参数类型如何也受到类型删除的影响。
继续 Section 4.6 of the JLS ,如上所述:
The type parameters of a constructor or method (§8.4.4), and the return type (§8.4.5) of a method, also undergo erasure if the constructor or method's signature is erased.
因此,删除的方法get
是
List get(List);
您的初始示例将无法编译,因为 Cls'
的方法签名s get
方法,get(List<List<Object>>)
不匹配原始接口(interface)的方法,也没有实现原始接口(interface)的get
方法。
这也是您的第二个和第三个示例编译的原因——它们正确地覆盖了原始接口(interface) Interface
.
顺便说一下,要覆盖通用的 Interface
接口(interface)而不求助于实现原始类型,在 implements
中提供一个类型参数子句:
public interface Interface<T> {
List<T> get(List<List<Object>> keys);
}
实现它:
class Cls<T> implements Interface<T> {
@Override
public List<T> get(List<List<Object>> keys) {
return Collections.emptyList();
}
}
或者
class Cls implements Interface<String> {
@Override
public List<String> get(List<List<Object>> keys) {
return Collections.emptyList();
}
}
任何引用类型都适用于 implements Interface<String>
, 只要类型匹配 get
中的返回类型.子句implements Interface<Integer>
将使用方法 List<Integer> get(List<List<Object>> keys)
.
简而言之,类型删除发生在原始类/接口(interface)中的所有参数化类型和泛型类型,无论它们是否与类/接口(interface)上声明的泛型类型参数相关。
关于java - 实现其中包含其他通用定义的原始接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20373692/