以下代码:
class Parent {
public void method(List parameter){
}
}
class Child extends Parent {
public void method(List<String> parameter) {
}
}
无法使用以下错误进行编译:
Parent.java:12: error: name clash: method(List<String>) in Child and method(List) in Parent have the same erasure, yet neither overrides the other
public void method(List<String> parameter) {
^
1 error
但我正在检查§8.4.8.1中的JLS8说:
在C类中声明或继承的实例方法mC,覆盖 来自C的另一种方法mA在A类中声明,iff以下全部 是的:
...
mC的签名是一个子签名(§8.4.2) mA的签名。
...
在§8.4.2中它说:
方法m1的签名是方法m2的签名的子签名,如果:
...
m1的签名与m2签名的擦除(§4.6)相同。
在这种情况下,原始方法和重写方法声明都具有相同的擦除,那么为什么编译失败了?
答案 0 :(得分:2)
因为在类型擦除之后,如果您愿意,只有List
(List<Object>
)。我想你想要一个通用的Parent
喜欢
class Parent<T> {
public void method(List<T> parameter){
}
}
class Child extends Parent<String> {
public void method(List<String> parameter) {
}
}
答案 1 :(得分:2)
在这种情况下,原始方法和重写方法声明都具有相同的擦除,那么为什么编译失败了?
同样的删除是不够的。再看看你引用的JLS部分:
方法m1的签名是a的签名的子签名 方法m2如果:
...
m1的签名与签名的擦除(§4.6)相同 m2。
这并不是说擦除必须是平等的。这就是说m1的签名必须删除m2的签名。我们不会在这里删除m1的签名。