Java:重载方法解析和varargs – 令人困惑的例子

正当我认为我理解JLS15.12应用于varargs时,这是这个例子:

package com.example.test.reflect; public class MethodResolutionTest2 { public int compute(Object obj1, Object obj2) { return 42; } public int compute(String s, Object... objects) { return 43; } public static void main(String[] args) { MethodResolutionTest2 mrt2 = new MethodResolutionTest2(); System.out.println(mrt2.compute("hi", mrt2)); System.out.println(mrt2.compute("hi", new Object[]{mrt2})); System.out.println(mrt2.compute("hi", new Object[]{mrt2, mrt2, mrt2})); } } 

打印出来的

 42 43 43 

我理解第一行: JLS15.12表示方法解析分阶段进行,第1阶段和第2阶段忽略varargs方法,以确定是否存在兼容方法,仅当阶段1和阶段2失败时才会发生阶段3(包括变量)。 (参见JLS和这个SO问题。 )因此compute(String s, Object... objects)如果compute(Object obj1, Object obj2)适用compute(Object obj1, Object obj2)则总是会忽略compute(String s, Object... objects)

但我不明白为什么43为其他两行打印。 Object[]也是Object[]一个实例,为什么它与varargs方法匹配?


编辑:

…还有这个

 Object arg2 = new Object[]{mrt2}; System.out.println(mrt2.compute("hi", arg2)); 

打印42

在第8.4.1节中:

如果最后一个forms参数是类型为T的变量arity参数,则认为它定义了类型为T[]的forms参数。

由于您明确提供了一个数组,因此允许后两个调用在第一阶段匹配变量arity方法,而不考虑变量arity。

可以使用多个参数(a,b,c)或作为数组({a,b,c})调用Vararg方法。 因为您传递的数组与varargs的类型相匹配,所以它优先。

参考: http : //java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.1