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

时间:2011-05-17 15:05:43

标签: java variadic-functions jls

正当我认为我理解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方法以确定是否存在兼容方法,第3阶段(包括varargs)仅在第1阶段发生和2失败。 (请参阅JLS和this SO question.)如果compute(String s, Object... objects)适用,则始终会忽略compute(Object obj1, Object obj2)

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


编辑:

......还有这个

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

打印42

2 个答案:

答案 0 :(得分:9)

8.4.1部分中:

  

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

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

答案 1 :(得分:4)

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

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