两个擦除方法相同的擦除方法不需要重写等价(或者它们的签名不是它们之间的子签名)? [英] Two methods with same erasure aren't necessary override-equivalent (or they signatures aren't subsignatures between them)?

查看:153
本文介绍了两个擦除方法相同的擦除方法不需要重写等价(或者它们的签名不是它们之间的子签名)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读jdk6的令人难以置信的书java程序员指南,以及关于通用重写的一节。在它上面描述了subsignature和override-equivalent,并且描述了一些与我引用的重写相同的例子:


给出以下三个泛型方法声明在课堂上:

static< T>无效合并(MyStack< T> s1,MyStack< T> s2){/*...*/}



静态< T> void merge(MyStack< T> s1,MyStack<?extends T> s2){/*...*/}

static< T> void merge(MyStack< T> s1,MyStack<?super T> s2){/*...*/}



,所有这三种方法的签名是: merge(MyStack,MyStack)
也就是说,方法的签名是覆盖等价的,因此这些方法
不会超载。


我并不完全同意这些方法是重写等价的,事实上我认为这些方法有一个通过擦除命名冲突,但没有一个是另一个的subignature ...可能是我错了,所以我想要在这个一些光。



子签名的定义使我认为它们之间不存在subsign。



在JSL 6#8.4中。 2方法签名( http:// docs。 oracle / javase / specs / jls / se6 / html / classes.html#8.4.2 如果它们具有相同的名称和参数类型,则具有相同的签名。
如果满足以下所有条件,则两个方法或构造函数声明M和N具有相同的参数类型:


  • 他们。具有相同数量的形式参数(可能为零)

  • 它们具有相同数量的类型参数(可能为零)


  • < A1,...,An> 为M的正式类型参数并让< B1,...,Bn> 是N的形式类型参数。在将N的类型中的每个Bi出现重命名为Ai后,相应类型变量的边界以及M和N的参数类型分别为相同。




方法m1的签名是方法m2的签名的子签名,如果
m2与m1具有相同的签名,或者m1的签名与m2的签名的删除相同b
$ p code> ...



如果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的签名的子签名,如果: p>


  • m2与m1具有相同的签名,或者

  • m1的签名与m2的签名的擦除相同。


    两个方法签名m1和m2是如果m1是m2或m2的子签名是m1的子签名,则覆盖等效项。




编辑1



简单来说,我的疑问是,从删除子签名的定义中,我明白
一个没有删除的签名等于从另一个签名删除而不是
擦除之后的两个签名都是相等的......其微妙而重要的
(顺便说一下,覆盖等价定义基于子签名定义,这就是为什么我要求)

解决方案

TL; DR



在我看来,这本书并没有很好地融合在一起。重载的定义是根据否定等效重写来定义的,如 JLS(8.4.9)(释义:如果存在两个名称相同的方法,但不是覆盖等效的,则它们将超载)。



但给出的例子是 NOT 覆盖等值的方法,但是 DO 由于其他原因导致编译时错误(名称冲突 - JLS 8.4.8.3 ),因此不会超负荷。





据我所知,你提出了一个关于这个句子的确切语义的问题:


...或者m1的签名与m2的签名的删除相同

结合


m1是m2或m2的子签名是m1的子签名。






您的书意味着这应该被解释为


或m1的 签名的 擦除与m2签名的擦除相同


(以斜体添加的单词)。



它作为


或m1( 没有删除 )的签名是与删除m2的签名相同


您的解释是正确的。我不认为该句子是不明确的,因此我认为以第一种方式解释(即两个签名的 擦除 是相同的)是不正确的。你可能想看看这个相关的答案来增加我的意见在这里的重量(我发现它,因为我想检查我的理解也是如此)。




回答(然而...)



<你引用的这部分内容实际上是试图描述超载。


现在 - 当考虑重载 - that:


如果一个类的两个方法(无论是在同一个类中声明的,还是由一个类继承的,或者一个声明的和一个继承的)具有相同的名称,但签名不是与覆盖等效的,那么方法名称被超载。

至少从Java 6开始,这一直是一致的。这就是覆盖等价和重载源于。

确定 - 所以你的方法会超载,因为它们不是严格的覆盖等值。对吗?



错误。



因为只是在放入特定的编译时间错误:

lockquote

如果一个类型声明T有一个成员方法m1并且存在一个在T中声明的方法m2,那么这是一个编译时错误或者超类型T,使得以下所有内容都是真实的:



查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆