Java 重载varargs数组,选择方法

Java 重载varargs数组,选择方法,java,overloading,Java,Overloading,我有两个重载方法:foo和bar //Object[]... vs Integer[]... public static String foo(Object[]... args) { return "Object[] args"; } public static String foo(Integer[]... args) { return "Integer[] args";} //Object... vs Integer[]... public static String bar(Objec

我有两个重载方法:
foo
bar

//Object[]... vs Integer[]...
public static String foo(Object[]... args)  { return "Object[] args"; }
public static String foo(Integer[]... args) { return "Integer[] args";}

//Object... vs Integer[]...
public static String bar(Object... args) {return "Object args";}
public static String bar(Integer[]... args) {return "Integer[] args";}
现在当我像这样使用它们时:

Integer[] i = { 5 };
System.out.println(foo(i));//Object[]... vs Integer[]...
System.out.println(bar(i));//Object... vs Integer[]...
我越来越

Integer[] args
Object args
问题是:为什么我们有两种不同的输出?

Integer[]
可以隐式转换为
Object
Object[]

在第一种情况下,args的类型实际上是Integer[][],即,您的数组被varargs装箱到另一个数组中。编译器选择Integer[]版本,因为它是最特定的类型

在第二种情况下,args==i,是一个整数[]。在这种情况下,编译器必须在将其包装到新数组中以调用整数[]之间进行选择。。。版本或仅将整数[]强制转换为对象[]。它选择了第二个,因为这是规则


这个故事的寓意是:不要重载varargs方法——这很令人困惑。

这基本上是编译器决定调用所有方法中最具体的方法

当你打电话的时候

System.out.println(foo(i));//Object[]... vs Integer[]...
它将调用
foo(整数[]…args)

因为在运行时,JVM将调用委托给带有
Integer[][]
参数的方法,而不使用varags指定的
Object[][]
param
的方法。因为使用整数[]而不是对象[]调用方法更为具体


在后面的语句中,当您调用

System.out.println(条(i))//对象vs整数[…]。

它将转到
栏(对象…参数)

同样,通过使用varags,param的类型将是Object[],而不是Object[]。同样,编译器将调用最具体的方法,即具有
对象的方法。。。args

如果您通过删除varags来更改方法签名,请按照以下步骤执行:

   //Object... vs Integer[]...
    public static String bar(Object args) {

        return "Object args";
    }

    public static String bar(Integer[] args) {
        return "Integer[] args";
    }
然后您会注意到,它将调用
条(Integer[]args)
,因为它更具体于方法调用

所以更准确地说,根据

  • 如果S和T都是引用类型,则S[]>T[]iff S>T
  • 对象>对象[]
这意味着将对具有整数[]而不是对象[]的方法调用整数[]。 其中,将对对象[]而不是整型[]调用整型[]


请参阅以选择最具体的方法。

对于那些想玩《神探夏洛克》的人,你至少应该提到编译器警告。@上校,是的,你可以,是的,你可以。当您尝试它时,您将得到一个运行时异常。我正在为Web开发人员使用EclipseJavaEEIDE。版本:Mars.1发行版(4.5.1)和Java8,没有任何警告:Integer[]arrayInts=newinteger[5];对象[]arrayObject=arrayInts;这是我的屏幕,你能找到说明
这是规则的规范位吗
?我可以。。。但是OP已经用他的编译器证明了这一点:)如果你能找到它,我会投票。我在破译它时遇到了困难。当你显式地提供一个数组时,参数匹配参数类型,而不需要“变量arity调用”,该方法将在搜索兼容方法的第1或第2阶段找到。否则,将执行第3阶段的搜索,以查找可以通过执行varargs包装来调用的方法。在第15.12节中有点分散