可变参数函数 - 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 方法以确定是否存在兼容的方法,阶段 3(包括 varargs)仅在阶段 1 和 2 失败时才发生。(请参阅JLS和此SO问题。因此,如果适用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 节中:

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

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

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

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

相关内容

  • 没有找到相关文章

最新更新