为什么这个重写方法声明会产生编译错误?

时间:2016-09-20 23:04:09

标签: java override method-overriding jls

以下代码:

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)相同。

在这种情况下,原始方法和重写方法声明都具有相同的擦除,那么为什么编译失败了?

2 个答案:

答案 0 :(得分:2)

因为在类型擦除之后,如果您愿意,只有ListList<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的签名。