Java 如何解释这些奇怪的擦除覆盖规则?

Java 如何解释这些奇怪的擦除覆盖规则?,java,generics,overriding,type-erasure,Java,Generics,Overriding,Type Erasure,这里发生了什么,如何理解 class C<T> { public T id(T x) { return null; } } class D extends C<String> { public Integer id(Integer x) { // compiles! but T shall be String ??? return 7; } } public static void main(S

这里发生了什么,如何理解

class C<T> {
    public T id(T x) {
        return null;
    }
}

class D extends C<String> {
    public Integer id(Integer x) {  // compiles! but T shall be String ???
        return 7;
    }
}

    public static void main(String[] args) {

        System.out.println(new D().id("7")); // null
        System.out.println(new D().id(7));   // 7

    }
C类{
公共T id(T x){
返回null;
}
}
D类扩展了C类{
公共整数id(整数x){//编译!但T应该是字符串???
返回7;
}
}
公共静态void main(字符串[]args){
System.out.println(新的D().id(“7”);//null
System.out.println(新的D().id(7));//7
}
顺便说一句,如果我像这样声明D,编译会失败,出现
名称冲突:类型D的方法id(对象)与类型C的id(T)具有相同的擦除,但不会覆盖它:

class D extends C<String> {
    public Object id(Object x) {   // compile error !
        return 7;
    }
}
D类扩展了C类{
公共对象id(对象x){//编译错误!
返回7;
}
}

在检查类型参数是否正确使用后,编译器会将其替换为
对象。因此,在编译之后,您的原始类
D
具有

public Object id(Object x)

这很好


但是,在第二个示例中,同一个类中有两个版本的
公共对象id(Object x)

使用@Override注释检查该方法是否确实重写了另一个方法

在第一种情况下,您将有两个方法,一个期望字符串,另一个期望整数


在第二种情况下,您创建了在超类型的类型擦除之后已经存在的相同方法

挑剔:在OP的示例中,C的id方法不是公共的。(仍为+1)
public Integer id(Integer x)