我遇到了一个示例,该示例表明在方法签名和方法上的擦除方式不同,但我不知道为什么/如何。JLS §8.4.8.3规定:
如果类型声明 T 具有成员方法 m1 并且存在在 T 中声明的方法 m2 或 T 的超类型,则编译时错误,并且满足以下所有条件:
- m1 和 m2 具有相同的名称。
- m2 可从 T 访问。
- m1 的签名不是 m2 签名的子签名(第 8.4.2 节)。
- m1 或某些方法 m1 覆盖(直接或间接)的签名与 m2 或某些方法 m2 覆盖(直接或间接)的签名具有相同的擦除。
给出的编译时错误示例:
class C<T> {
T id (T x) {...}
}
class D extends C<String> {
Object id(Object x) {...}
}
说明:
这是非法的,因为 D.id(Object) 是 D 的成员,C.id(String) 在 D 的超类型中声明,并且:
- 这两个方法具有相同的名称,id
- D 可以访问 C.id(String)
- D.id(Object) 的签名不是 C.id(String) 的子签名
- 这两种方法具有相同的擦除
前两点很明显,但我不明白解释的最后两点。如果第三点成立,这两种方法如何具有相同的擦除?从第三点来看,签名的擦除似乎是使用参数化类 C<String> 的方法(即 id(String) 而不是 id(T))完成的。如果是这种情况,那么这两个方法应该有不同的擦除,但是该示例表明方法擦除是在非参数化类上完成的。那么,擦除实际上是如何应用于方法签名和方法的呢?