13

就在我以为我理解JLS15.12应用于可变参数时,下面是这个例子:

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(包括 varargs)。(请参阅 JLS 和这个 SO 问题。)所以如果适用,compute(String s, Object... objects)总是会被忽略。compute(Object obj1, Object obj2)

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


编辑:

...还有这个

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

打印42

4

2 回答 2

9

在第8.4.1节中:

如果最后一个形参是类型的可变参数T,则认为定义了一个类型的形参T[]

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

于 2011-05-17T15:22:43.653 回答
4

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

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

于 2011-05-17T15:10:23.277 回答