Java 重写泛型类的方法时发生名称冲突

Java 重写泛型类的方法时发生名称冲突,java,generics,overriding,name-clash,Java,Generics,Overriding,Name Clash,我正在尝试理解使用以下代码得到的名称冲突错误: import java.util.*; import javax.swing.*; class Foo<R extends Number> { public void doSomething(Number n, Map<String, JComponent> comps) { } } class Bar extends Foo { public void doSomething(Number n,

我正在尝试理解使用以下代码得到的名称冲突错误:

import java.util.*;
import javax.swing.*;

class Foo<R extends Number> {
    public void doSomething(Number n, Map<String, JComponent> comps) {
    }
}

class Bar extends Foo {
    public void doSomething(Number n, Map<String, JComponent> comps) {
    }
}
import java.util.*;
导入javax.swing.*;
福班{
公共无效剂量仪(编号n,地图组件){
}
}
类栏扩展了Foo{
公共无效剂量仪(编号n,地图组件){
}
}
错误消息:

错误:名称冲突:
doSomething(数字、地图)
栏中
和
doSomething(Number,Map)
Foo中的
doSomething(Number,Map)
擦除,但两者都不能覆盖另一个

我知道我可以通过从
Foo
中删除泛型类型,或者将
Bar
声明更改为
class Bar extensed Foo
来修复它;我想知道的是,为什么在特定情况下会发生此错误,但如果我从每个方法中删除
comps
参数,错误就会消失。我已经读了一些关于的书,但在我看来,这两种方法都应该具有相同的擦除,无论是否使用泛型,因此在任何情况下都是有效的重写。(请注意,我甚至还没有在任何地方使用泛型参数,这就是为什么我如此惊讶的原因。)

我知道我以前已经向父类添加了泛型类型,但只得到了关于子类的警告,而没有错误。有人能解释一下这种情况吗?

这是一个错误的结果

类的超类型可以是原始类型。用户的成员访问权限 类被视为正常,并且超类型的成员访问被忽略 按原始类型处理。在类的构造函数中,调用 super被视为对原始类型的方法调用

这在调用超类型方法时适用,但在重写超类型方法时也适用

以下面的例子为例

class Bar extends Foo {
    public Bar() {
        doSomething(1, new HashMap<Number, String>());
    }
}
换句话说,类型参数的每次使用都会被删除。因此,尝试声明该方法

public void doSomething(Number n, Map<String, JComponent> comps) {
}
进一步阅读:


您正在扩展raw
Foo
@LuiggiMendoza是的,我知道,问题是为什么Java认为当两个方法都不使用泛型参数时,这些方法具有不同的擦除,以及为什么如果我从这两个方法中删除
comps
参数,它会感到高兴。可能与此有关,但我看不到。
Map
接口使用泛型,这可能就是它抱怨的原因。您使用的是哪种特定版本的Java?具体来说,我指的是java 6 u30或java 7 u40。@LuiggiMendoza我使用Eclipse Luna和JDK1.7.0_55,也在ideone.com上测试过,不确定他们使用的是哪个版本。@Stroboskop我看过一些关于这方面的帖子,但Eclipse在这里似乎没有错
javac
给了我同样的结果,特别是关于重载和重写的解释。(线索在错误消息中,但我非常惊讶,竟然错过了它们。)为了进一步解释,如果子类未能指定类级泛型参数,从子类的角度来看,即使父类中完全不相关的泛型参数也将有效地停止存在?@brad除了在
静态
方法中的泛型用法之外的所有内容。
public void doSomething(Number n, Map<String, JComponent> comps) {
}
public void doSomething(Number n, Map comps) {
}