gpt4 book ai didi

java - JLS 关于方法覆盖和泛型是否完整?

转载 作者:行者123 更新时间:2023-12-04 10:02:21 25 4
gpt4 key购买 nike

所以,我试图写一种方法来回答我之前的一个问题:How can I find out if an arbitrary java.lang.Method overrides another one?为此,我正在阅读 JLS,在一个案例中似乎缺少某些部分。

假设您有以下类:

public class A<T> {
public void foo(T param){};
}

public class B extends A<String> {
public void foo(String param){};
}

在这种情况下,很明显 B.foo覆盖 A.foo ,但是我不明白这种情况如何符合规范。

关于方法覆盖, JLS §8.4.8.1状态:

An instance method m1, declared in class C, overrides another instance method m2, declared in class A iff all of the following are true:

  1. C is a subclass of A.

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

  3. Either:

    • m2 is public, protected, or declared with default access in the same package as C,or
    • m1 overrides a method m3 (m3 distinct from m1, m3 distinct from m2), such that m3 overrides m2.


显然,在我们的案例中,第 1 点和第 3 点是满足的。让我们在 JLS 中更深入地了解子签名的含义。 JLS §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:

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

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

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



在我们的例子中,第 1 点显然是正确的(两者都有 1 个参数)。

第 2 点有点困惑(这就是我不确定规范的确切含义的地方):这两个方法都没有声明自己的类型参数,但是 A.foo用途 T这是一个参数化类的类型变量。

所以我的第一个问题是:在这种情况下, 在类中声明的类型变量是否计数?

好的,现在让我们假设 T不算数,因此第 2 点是错误的(我不知道在这种情况下我什至如何应用第 3 点)。我们的两种方法没有相同的签名,但这并不能阻止 B.foo来自 A.foo 的子签名.

JLS §8.4.2 更远一点它说:

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

  1. m2 has the same signature as m1, or

  2. the signature of m1 is the same as the erasure (§4.6) of the signature of m2.



我们已经确定第 1 点是错误的。

根据 JLS §4.6 的方法的删除签名是 a signature consisting of the same name as s and the erasures of all the formal parameter types given in s .所以A.foo的删除是 foo(Object)而 B.foo 的删除是 foo(String) .这两个是不同的签名,因此第 2 点也是假的,并且 B.foo 不是 A.foo 的子签名,因此 B.foo 不会覆盖 A.foo。

除了它...

我错过了什么?是否有一些我没有看到的难题,或者在这种情况下规范真的不完整?

最佳答案

do Type variables declared in the class count or not?



有问题的元素是方法,而不是包含的类型声明。所以,不,他们不算数。

Ok, now let's assume that T doesn't count and that therefore point 2 is false



为什么?它们都有 0 个类型参数,所以这是真的。

一步步:

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


这两种方法都有 1 个形式参数。查看。

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


这两种方法都没有声明类型参数。查看。

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



由于这两种方法都没有声明类型参数,因此无需重命名并且形式参数类型相同 -- T[T=String] = String .查看。

B.foo(String)A<String>.foo(String) 具有相同的签名.
B.foo(String)A<String>.foo(String) 的子签名

BA 的子类和 A<String>.foo(String)公开我们可以 conclude B.foo(String)覆盖 A<String>.foo(String) .

关于java - JLS 关于方法覆盖和泛型是否完整?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12154731/

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