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

Ulr*_*olz 7 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
}
Run Code Online (Sandbox Code Playgroud)

第2集:

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

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

public void b() {
    test(1, "y"); // marked as ambiguous
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

Java 1.8,Eclipse Oxygen

Ste*_*n C 5

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

A型S是不是类型更具体的T,如果对任意表达式S <: T(§4.10).

where S <: T表示S是的子类型T.

在示例#1中:

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

在示例#2中:

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


dan*_*niu 1

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

在第二种情况下,有两个选择——拳击或不拳击。这就是它变得含糊不清的原因。

我同意这是违反直觉的。