gpt4 book ai didi

java - 具有相同删除的两种方法不一定是等效的(或者它们之间的签名不是子签名)?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:56:48 26 4
gpt4 key购买 nike

我正在阅读一本关于 jdk6 的令人难以置信的书“java scjp 认证程序员指南”,其中有一节是关于泛型覆盖的。它描述了子签名和覆盖等价物,并描述了我引用的一些覆盖等价物的例子:

Given the following three generic method declarations in a class:

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) { /*...*/ }

After erasure, the signature of all three methods is: merge(MyStack, MyStack) i.e., the signatures of the methods are override-equivalent, hence these methods are not overloaded.

我不完全同意这些方法是覆盖等效的,事实上我认为这些方法有一个“删除的名称冲突”但没有一个是另一个的子签名......可能我错了所以我想对此有所了解。

subsignature 的定义让我觉得它们之间不是subsignatures。

在 JSL 6 #8.4.2 方法签名中 ( http://docs.oracle.com/javase/specs/jls/se6/html/classes.html#8.4.2 )

Two methods have the same signature if they have the same name and argument types. Two method or constructor declarations M and N have the same argument types if all of the following conditions hold:

  • They. have the same number of formal parameters (possibly zero)

  • They have the same number of type parameters (possibly zero)

  • Let <A1,...,An> be the formal type parameters of M and let <B1,...,Bn> be the formal type parameters of N. After renaming each occurrence of a Bi in N's type to Ai the bounds of corresponding type variables and the argument types of M and N are the same.

The signature of a method m1 is a subsignature of the signature of a method m2 if either m2 has the same signature as m1, or the signature of m1 is the same as the erasure of the signature of m2

...

Two method signatures m1 and m2 are override-equivalent iff either m1 is a subsignature of m2 or m2 is a subsignature of m1.

在 JSL 8 # 8.4.2 中。方法签名 ( http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.2 )

Two methods or constructors, M and N, have the same signature if they have the same name, the same type parameters (if any) (§8.4.4), and, after adapting the formal parameter types of N to the the type parameters of M, the same formal parameter types.

The signature of a method m1 is a subsignature of the signature of a method m2 if either:

  • m2 has the same signature as m1, or

  • the signature of m1 is the same as the erasure of the signature of m2.

Two method signatures m1 and m2 are override-equivalent iff either m1 is a subsignature of m2 or m2 is a subsignature of m1.

编辑 1

简单来说,我怀疑从关于删除的子签名定义我理解“一个没有删除的签名等于从另一个签名中删除”..而不是“删除后的两个签名是相等的”..它微妙但重要(顺便说一下,覆盖等价定义是基于子签名定义的,这就是为什么我要问子签名的原因)

最佳答案

长话短说

在我看来,这本书的措辞并没有很好地结合在一起。根据 JLS (8.4.9),重载是根据对覆盖等效性的否定来定义的(换句话说:如果存在两个具有相同名称的方法但不是覆盖等效的,那么它们将重载)。

但给出的示例中的方法不是覆盖等效,但DO导致其他原因导致的编译时错误(名称冲突 - JLS 8.4.8.3 中指定的特定编译时错误),因此不要重载。


序言

据我了解,您提出的问题是关于这句话从句的确切语义:

"...or the signature of m1 is the same as the erasure of the signature of m2"

结合

m1 and m2 are override-equivalent iff either m1 is a subsignature of m2 or m2 is a subsignature of m1.


你的书暗示这应该解释为

"or the erasure of the signature of m1 is the same as the erasure of the signature of m2"

(添加的单词以粗斜体显示)。

而你会把它解释为

"or the signature of m1 (without erasure) is the same as the erasure of the signature of m2"

你的解释是正确的。我不认为这句话有歧义,因此我认为以第一种方式解释它(即 删除 两个签名是相同的)是不正确的。你可能喜欢 look at this related answer在这里增加我的意见(我发现它是因为我也想检查我的理解)。


回答(然而...)

您引用的那本书的部分实际上是在描述重载。

现在 - 当考虑重载时 - JLS (8.4.9) says那:

If two methods of a class (whether both declared in the same class, or both inherited by a class, or one declared and one inherited) have the same name but signatures that are not override-equivalent, then the method name is said to be overloaded.

这至少从 Java 6 开始就是一致的。这就是 override-equivalent 和重载之间的联系的来源。

好的 - 所以你的方法会重载,因为它们不是严格的重写等效的。对吧?

错了。

因为就在那一节的上方in 8.4.8.3, the JLS放入特定的编译时错误:

It is a compile-time error if a type declaration T has a member method m1 and there exists a method m2 declared in T or a supertype of T such that all of the following are true:

  • m1 and m2 have the same name.

  • m2 is accessible from T.

  • The signature of m1 is not a subsignature (§8.4.2) of the signature of m2.

  • The signature of m1 or some method m1 overrides (directly or indirectly) has the same erasure as the signature of m2 or some method m2 overrides (directly or indirectly).

这是您示例中的场景。就在该部分的下方,它阐明了为什么有必要:

These restrictions are necessary because generics are implemented via erasure. The rule above implies that methods declared in the same class with the same name must have different erasures. It also implies that a type declaration cannot implement or extend two distinct invocations of the same generic interface.

旁注

书中的例子很奇怪,因为 Java 不允许覆盖静态方法(子类中方法的签名可以隐藏父类(super class)中的方法)。在我看来,这使得不被覆盖等效的概念对于学习者来说有点棘手。但是,您可以删除 static 并仍然看到他们试图展示的效果。

关于java - 具有相同删除的两种方法不一定是等效的(或者它们之间的签名不是子签名)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31225155/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com