如何解释这些带有擦除的奇怪覆盖规则?
How these strange override rules with erasure can be explained?
这里发生了什么以及如何理解它?
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
}
顺便说一下,如果我这样声明 D,编译会失败 Name clash: The method id(Object) of type D has the same erasure as id(T) of type C<T> but does not override it:
class D extends C<String> {
public Object id(Object x) { // compile error !
return 7;
}
}
编译器在检查您的类型参数是否已被正确使用后,会将您的类型参数替换为 Object
。所以编译后,你原来的classD
有
public Object id(Object x)
和
public Integer id(Integer x)
非常好。
但是,在您的第二个示例中,同一个 class 中有两个版本的 public Object id(Object x)
。
使用@Override 注解检查该方法是否真的覆盖了另一个方法。
在第一种情况下,您将有 2 个方法,一个需要 String,另一个需要 Integer。
在第二种情况下,您创建了相同的方法,该方法在超类型的类型擦除后已经存在。
这里发生了什么以及如何理解它?
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
}
顺便说一下,如果我这样声明 D,编译会失败 Name clash: The method id(Object) of type D has the same erasure as id(T) of type C<T> but does not override it:
class D extends C<String> {
public Object id(Object x) { // compile error !
return 7;
}
}
编译器在检查您的类型参数是否已被正确使用后,会将您的类型参数替换为 Object
。所以编译后,你原来的classD
有
public Object id(Object x)
和
public Integer id(Integer x)
非常好。
但是,在您的第二个示例中,同一个 class 中有两个版本的 public Object id(Object x)
。
使用@Override 注解检查该方法是否真的覆盖了另一个方法。
在第一种情况下,您将有 2 个方法,一个需要 String,另一个需要 Integer。
在第二种情况下,您创建了相同的方法,该方法在超类型的类型擦除后已经存在。