我正在阅读关于 jdk6 的令人难以置信的书“java scjp 认证程序员指南”,其中有一个关于泛型覆盖的部分。上面描述了 subsignature 和 override-equivalent 并描述了一些我引用的 override-equivalent 示例:
给定一个类中的以下三个泛型方法声明:
static <T> void merge (MyStack<T> s1, MyStack<T> s2) { /*...*/ }
static <T> void merge (MyStack<T> s1, MyStack<? extends T> s2) { /*...*/ }
static <T> void merge (MyStack<T> s1, MyStack<? super T> s2) { /*...*/ }
擦除后,所有三个方法的签名都是:
merge(MyStack, MyStack)
即,方法的签名是重写等效的,因此这些方法不会被重载。
我不完全同意这些方法是等效的,事实上我认为这些方法有“名称冲突由擦除”但没有一个是另一个的子签名……可能我错了,所以我想对此有所了解。
子签名的定义让我认为它们不是它们之间的子签名。
在 JSL 6 #8.4.2 方法签名中 ( http://docs.oracle.com/javase/specs/jls/se6/html/classes.html#8.4.2 )
如果两个方法具有相同的名称和参数类型,则它们具有相同的签名。如果满足以下所有条件,则两个方法或构造函数声明 M 和 N 具有相同的参数类型:
他们。具有相同数量的形式参数(可能为零)
它们具有相同数量的类型参数(可能为零)
令
<A1,...,An>
为 M 的形式类型参数,令<B1,...,Bn>
为 N 的形式类型参数。将 N 的类型中出现的 Bi 重命名为 Ai 后,相应类型变量的边界以及 M 和 N 的参数类型相同。如果 m2 与 m1 具有相同的签名,或者 m1 的签名与擦除 m2 的签名相同,则方法 m1 的签名是方法 m2 的签名的子签名
...
如果 m1 是 m2 的子签名或 m2 是 m1 的子签名,则两个方法签名 m1 和 m2 是覆盖等效的。
在 JSL 8 # 8.4.2 中。方法签名(http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.2)
如果两个方法或构造函数 M 和 N 具有相同的名称、相同的类型参数(如果有)(第 8.4.4 节),并且在将 N 的形式参数类型调整为类型参数之后,则它们具有相同的签名的 M,形参类型相同。
方法 m1 的签名是方法 m2 签名的子签名,如果:
m2 与 m1 具有相同的签名,或
m1 的签名与 m2 的签名擦除相同。
如果 m1 是 m2 的子签名或 m2 是 m1 的子签名,则两个方法签名 m1 和 m2 是覆盖等效的。
编辑 1
简而言之,我的疑问是,从关于擦除的子签名定义中,我理解“一个没有擦除的签名等于从另一个签名中擦除”..而不是“擦除后的两个签名相等”..它微妙但重要(顺便说一下,等效的覆盖定义是基于子签名定义的,这就是为什么我在子签名方面提出问题)