首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有Object和primitive类型的歧义varargs方法

具有Object和primitive类型的歧义varargs方法
EN

Stack Overflow用户
提问于 2017-09-04 21:07:02
回答 3查看 193关注 0票数 7

考虑以下两组方法。第一个被接受,第二个被拒绝为模棱两可。唯一的区别是使用int和Integer。

有没有特别需要拒绝第二个?这意味着在装箱后接受它(这将导致第一组)有一个问题。我在这里错过了什么?

在我看来,Java编译器在这方面的限制太大了。

Set 1:

代码语言:javascript
复制
public void test(Object... values) {}

public void test(Integer x, Object... values) {} // difference here

public void b() {
    test(1, "y"); // accepted
}

Set 2:

代码语言:javascript
复制
public void test(Object... values) {}

public void test(int x, Object... values) {} // difference here

public void b() {
    test(1, "y"); // marked as ambiguous
}

Set 2产生编译器错误:

代码语言:javascript
复制
 error: reference to test is ambiguous
    test(1, "y"); // marked as ambiguous
    ^
  both method test(Object...) in T and method test(int,Object...) in T match

Java 1.8,Eclipse Oxygen

EN

回答 3

Stack Overflow用户

发布于 2017-09-04 21:26:02

编译器所做的是实现JLS 15.12.2.5中设置的规则,以便在多个方法适用于调用的情况下选择最具体的方法。在您的问题中的示例中,规格中的这一行涵盖了差异:

对于任何表达式if S <: T,类型S比类型T更具体(§4.10)。

其中,S <: T表示ST的子类型。

在示例1中:

  • 有两种适用的方法
  • IntegerObject的子类型,因此它更具体第二种方法比first.
  • Therefore更具体选择第二种方法。

在示例2中:

  • 有两种适用的方法
  • 类型int不是Object的子类型,反之亦然,因此这两种类型都不比另一种更具体。因此,这两种方法都比other.
  • Therefore更具体,
  • 调用是不明确的。
票数 5
EN

Stack Overflow用户

发布于 2017-09-04 21:22:52

不同之处在于,在第一种情况下,需要将1参数装箱到整数中,然后选择最合适的方法;即(Integer, Object...)版本。

在第二种情况下,有两个选项-装箱或不装箱。这就是它的模棱两可的原因。

我同意这是违反直觉的。

票数 1
EN

Stack Overflow用户

发布于 2017-09-11 14:51:24

为了结束这个问题,让我总结一下我所理解的问题的实际答案:根据规范,行为是正确的。该规范可以放宽,使得原始类型作为它们的非原始对等类型被涵盖。一个尚未完成的原因是指定和实现一个快速而正确的解析器的复杂性。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46037767

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档