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

Java 为什么这个重写方法声明会产生编译错误?,java,overriding,jls,Java,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 an

以下代码:

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中声明或由类C继承的实例方法mC重写 从C开始,在类A中声明另一个方法mA 是真的:

mC的签名是本协议§8.4.2的子签名 马的签名

在§8.4.2中指出:

方法m1的签名是方法m2签名的子签名,如果:

m1的签名与m2签名的删除§4.6相同


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

因为在类型擦除之后,如果您愿意,只有列表。我想你想要一个像我这样的普通父母


因为,在类型擦除之后,如果您愿意,只有列表。我想你想要一个像我这样的普通父母

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

同样的擦除是不够的。再看看您引用的JLS部分:

方法m1的签名是方法m1的签名的子签名 方法m2,如果:

m1的签名与签名的擦除§4.6相同 平方米

这并不是说擦除必须相等。这意味着m1的签名必须是m2签名的擦除。我们不会在这里删除m1的签名

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

同样的擦除是不够的。再看看您引用的JLS部分:

方法m1的签名是方法m1的签名的子签名 方法m2,如果:

m1的签名与签名的擦除§4.6相同 平方米


这并不是说擦除必须相等。这意味着m1的签名必须是m2签名的擦除。我们这里没有删除m1的签名。

List不是删除List,所以根据您引用的规范,它不是子签名。我想你把m1和m2弄混了。它们不是都被认为是类型擦除到列表吗?它们都是类型擦除到列表,但你引用的规范不是关于它们是否有共同的擦除,而是关于子类的方法是否是超类的方法的擦除。如果父类有List,子类有List,您就可以了。@4castle,我明白了,我在问题中弄错了,我该怎么办?编辑问题?或者删除它,因为问题本身的表述不正确?列表不是删除列表,所以根据您引用的规范,它不是子签名。我想你把m1和m2弄混了。它们不是都被认为是类型擦除到列表吗?它们都是类型擦除到列表,但你引用的规范不是关于它们是否有共同的擦除,而是关于子类的方法是否是超类的方法的擦除。如果父类有List,子类有List,您就可以了。@4castle,我明白了,我在问题中弄错了,我该怎么办?编辑问题?或者删除它,因为问题本身没有正确表述?我不确定你的第一句话是否回答了这个问题,因为OP提出了一个类似的理由来解释为什么它不应该是一个编译器错误。实际的父类属于一个遗留库,但无论如何,我并不是在寻找一个解决方案,而是编译器这样做的原因。@JaimeHablutzel,这样,像您在这里看到的遗留代码在添加泛型类型的情况下继续运行这几乎完全是一个编译时类型检查系统我不确定你的第一句话是否回答了这个问题,因为OP提出了一个类似的理由来解释为什么它不应该是一个编译器错误。实际的父类属于一个遗留库,但无论如何,我并不是在寻找一个解决方案,而是编译器这样做的原因。@JaimeHablutzel,这样,像您在这里看到的遗留代码在添加泛型类型的情况下继续运行在这种情况下,类父{void methodList参数{}}类子扩展父{void methodList参数{}}应该编译为m1的签名与删除m2的签名相同,但事实并非如此。@JaimeHablutzel:m1和m2是另一种情况。m1和m2指的是正确的方法,我之前评论中的示例的问题是List is is List而只是List的类型擦除。下面的示例说明了m1何时与m2签名的擦除相同,并且其工作正常
rectly类父{void methodList foo{}}class子类扩展了父{void methodList bar{}。您的答案实际上是指出了将我的问题表述为@4castle的问题。我是否应该编辑公式错误的问题,还是应该删除它,因为如果它只是问为什么这个重写方法声明会产生编译错误,那么您的答案将不适用?没有引用我没有正确解释的JLS?在这种情况下,类父{void methodList参数{}}类子扩展父{void methodList参数{}}应该编译为m1的签名与删除m2的签名相同,但事实并非如此。@JaimeHablutzel:m1和m2是另一种情况。m1和m2指的是正确的方法,我之前评论中的示例的问题是List is is List而只是List的类型擦除。下面的示例说明了m1何时与m2签名的擦除相同,并且它正确工作,类父{void methodList foo{}}类子扩展父{void methodList bar{}。您的答案实际上也指出了将我的问题表述为@4castle的问题。我是否应该编辑公式错误的问题,还是应该删除它,因为如果它只是问为什么这个重写方法声明会产生编译错误,那么您的答案将不适用?没有引用我没有正确解释的JLS?。
class Parent<T> {
    public void method(List<T> parameter){
    }
}

class Child extends Parent<String> {
    public void method(List<String> parameter) {
    }
}