java – 使用原始类型和包装类的varargs重载时为什么会出现模糊错误?

参见英文答案 > Ambiguous varargs methods4个
我不明白为什么在这里的情况1,它没有给出编译错误,相反在情况2(varargs),它给出了编译错误.任何人都可以详细说明编译器在这两种情况下的差异吗?我经历了很多关于它的帖子,但还不能理解它.

情况1

public class Test {

    public void display(int a) {
        System.out.println("1");
    }

    public void display(Integer a) {
        System.out.println("2");
    }

    public static void main(String[] args) {
        new test().display(0);
    }
}

输出为:1

案例#2

public class Test {

    public void display(int... a) {
        System.out.println("1");
    }

    public void display(Integer... a) {
        System.out.println("2");
    }

    public static void main(String[] args) {
        new test().display(0);
    }
}

编译错误

The method display(int[]) is ambiguous for the type Test

解决方法

在第一个示例中,display(int)方法在严格调用上下文中调用,而display(Integer)在松散调用上下文中调用(因为需要自动装箱).因此编译器根据JLS选择display(int)方法.调用上下文在这里解释 JLS 5.3. Invocation Contexts

在第二个示例中,两个方法都在松散的调用上下文中调用,因此编译器需要找到最具体的方法JLS 15.12.2.5 Choosing the Most Specific Method.由于int不是Integer的子类型,因此没有最具体的方法,编译器会抛出编译错误.

你可以在Method overload ambiguity with Java 8 ternary conditional and unboxed primitives找到类似编译错误的解释

适用于此案例的部分:

Identifying applicable methods is divided into 3 phases.

The first phase (§15.12.2.2) performs overload resolution without
permitting Boxing or unBoxing conversion,or the use of variable
arity method invocation
. If no applicable method is found during
this phase then processing continues to the second phase.

The second phase (§15.12.2.3) performs overload resolution while
allowing Boxing and unBoxing,but still precludes the use of
variable arity method invocation
. If no applicable method is found
during this phase then processing continues to the third phase.

The third phase (§15.12.2.4) allows overloading to be combined with
variable arity methods,Boxing,and unBoxing.

对于第一个示例,只有display(int)方法在第一个阶段匹配,因此选择它.对于第二个示例,两个方法在第三阶段匹配,因此选择最具体方法算法发挥作用JLS 15.12.2.5 Choosing the Most Specific Method

m2 is not generic,and m1 and m2 are applicable by variable arity
invocation,and where the first k variable arity parameter types of m1
are S1,…,Sk and the first k variable arity parameter types of m2
are T1,Tk,the type Si is more specific than Ti for argument ei
for all i (1 ≤ i ≤ k). Additionally,if m2 has k+1 parameters,then
the k+1’th variable arity parameter type of m1 is a subtype of the
k+1’th variable arity parameter type of m2.

如前所述,由于int&lt ;: Integer不满足,因此没有最具体的方法.

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...