具有Object和原始类型的不明确的varargs方法

时间:2017-09-04 13:07:02

标签: java variadic-functions primitive-types

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

是否特别需要拒绝第二个?这意味着在拳击之后接受它(这将导致第一组)有一个问题。我在这里想念什么?

从我的角度来看,这里的Java编译器太局限了。

设置1:

public void test(Object... values) {}

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

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

设置2:

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产生编译器错误:

 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

3 个答案:

答案 0 :(得分:5)

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

  

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

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

在示例#1中:

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

在示例#2中:

  • 有两种适用的方法
  • 类型int不是Object的子类型,反之亦然,因此两种类型都不比另一种更具体。
  • 因此,这两种方法都不比其他方法更具体。
  • 因此调用不明确。

答案 1 :(得分:1)

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

在第二种情况下,有两种选择 - 拳击与否。这就是模糊不清的原因。

我同意这是违反直觉的。

答案 2 :(得分:0)

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