为什么一处的原始类型会导致其他地方的通用调用点被视为原始类型?

发布于 2024-11-09 13:07:38 字数 675 浏览 0 评论 0原文

考虑这个例子:

import java.util.*;

class Foo<T> {
  public int baz(List<String> stringlist) { return 1; }
  public int baz(ArrayList<Object> objectlist) { return 2; }

  public static void main(String[] args) {
    Foo<String> foo = new Foo<String>(); // (A)
    //Foo foo = new Foo();               // (B)

    System.out.println(foo.baz(new ArrayList<String>()));
  }
}

为什么它在 (A) 中打印 1,而在 (B) 中打印 2

我知道方法解析是如何工作的,所以不需要向我解释。

我想知道这个“功能”背后更深层的动机。 为什么没有关于它的删除警告? (只有一个关于Foo foo = new Foo()。)

尽管给出了泛型类型,为什么方法解析使用擦除语义?

Consider this example:

import java.util.*;

class Foo<T> {
  public int baz(List<String> stringlist) { return 1; }
  public int baz(ArrayList<Object> objectlist) { return 2; }

  public static void main(String[] args) {
    Foo<String> foo = new Foo<String>(); // (A)
    //Foo foo = new Foo();               // (B)

    System.out.println(foo.baz(new ArrayList<String>()));
  }
}

Why does it print 1 in (A), but 2 with (B)?

I know how method resolution works, so no need to explain that to me.

I want to know the deeper motivation behind this "feature".
Why is there no erasure warning about it? (There is just one about Foo foo = new Foo().)

Why does method resolution use erased semantics although the generic type is given?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我纯我任性 2024-11-16 13:07:38

这是因为当编译器解决重载时,它会将每个方法视为通用方法或非泛型,绝不是两者的混合,因此候选者是:

  1. Foo.baz(List)
  2. Foo.baz(ArrayList; )

如果 fooFoo,或

  1. Foo.baz(List)
  2. Foo.baz(ArrayList )

如果 fooFoo

不存在 Foo.baz(List) 这样的东西。要么考虑所有类型参数,要么不考虑。 (我不知道 JLS 中明确指出了这一点,但这是有道理的,因为将泛型方法视为原始等效方法是一种向后兼容性功能。)

在第一种情况下,Foo.baz(List) 匹配,但 Foo.baz(ArrayList) 不匹配。

在第二种情况下,两个函数都匹配,并且 Foo.baz(ArrayList)更具体,所以选择了。

It's because when the compiler is resolving overloads, it considers each method as either generic or non-generic, never a mixture of the two, so the candidates are:

  1. Foo<T>.baz(List<String>)
  2. Foo<T>.baz(ArrayList<Object>)

if foo is a Foo<String>, or

  1. Foo.baz(List)
  2. Foo.baz(ArrayList)

if foo is a Foo.

There is no such thing as Foo.baz(List<String>). Either all type parameters are considered or none are. (I am not aware of this being explicitly stated in the JLS, but it makes sense since treating a generic method as if it were the raw equivalent is a backwards-compatibility feature.)

In the first case, Foo<T>.baz(List<String>) matches but Foo<T>.baz(ArrayList<Object>) does not.

In the second case both functions match, and Foo.baz(ArrayList) is more specific, so it is chosen.

小女人ら 2024-11-16 13:07:38

如果只保留单个方法 baz(ArrayList) ,它甚至不会编译情况 (A)(错误:方法无法应用于给定类型)。
我猜 ArrayList 不是 ArrayList的子类。

奇怪的是它确实在情况 (B) 中编译,但他们一定采取了一些奇怪的决定来保持与非泛型集合的向后兼容性。

It won't even compile case (A) if you only keep the single method baz(ArrayList<Object>) (error: method cannot be applied to given type).
I guess ArrayList<String> is not a subclass of ArrayList<Object>.

It's weird that it does compile in case (B), but they must have taken some weird decisions to kept backward compatibility with non-generic collections.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文