varargs和歧义的概念?

时间:2013-11-24 18:36:55

标签: java compiler-errors variadic-functions ambiguity java-5

以下是一个例子:

package com.demo;
public class PassArray {
    static void vaTest(int... v){
        System.out.println("no of args : "+v.length+"contents: ");
        for (int x:v){
            System.out.println(x+" ");
        }
    }
    static void vaTest(boolean... v){
        System.out.println("no of args : "+v.length+"contents: ");
        for (boolean x:v){
            System.out.println(x+" ");

        }
    }
    public static void main(String args[]){

        vaTest(1,2,3);
        vaTest(true,false,true);
        vaTest();//Error:Ambiguous!
    }
}

任何人都可以告诉我:

我有一些问题

1.为什么会出现模棱两可的错误?

2.i有一个Varargs参数,就像

一样
int doIt(int a,int b,int c,int... vals)

为什么必须最后声明varargs?

  1. 什么是varargs和歧义?

3 个答案:

答案 0 :(得分:5)

由于调用vaTest();有两个合法的方法调用,编译器无法确定要使用哪一个。
为了帮助它,您可以提供所选类型的空数组:

vaTest(new int[] {});

JLS 15.12.2.5. Choosing the Most Specific Method中提供了更多信息。

答案 1 :(得分:2)

  

为什么会出现模糊错误?

因为你没有传递任何参数,并且这两个方法都是调用的有效候选者,因为两者都可以在没有任何参数的情况下被调用。编译器无法决定绑定方法调用的方法,因为没有参数类型来区分方法。

  

为什么必须最后声明varargs?

好吧,因为那就是创建Java的人希望它被声明的方式。可能是他们希望编译器的任务变得容易。如果将varargs声明为最后一个参数,编译器可以继续将最后一个非vararg参数之后的所有参数绑定到vararg参数。当然,即使vararg被允许在中间的某个位置也是可能的,但是这需要编译器首先将参数绑定到末端,或者至少某种算法以找出有足够的参数留给绑定到其他非vararg参数。这会使解析变得复杂,因为编译器从左到右绑定方法参数(这需要进行一些更改)。可能是语言创建者的想法,添加此功能不会有太大的作用来证明编译器如何绑定参数的变化。所以,这个限制。

答案 2 :(得分:1)

  

1.为什么会出现模棱两可的错误?

这部分已经被其他用户很好地回答了。

  

为什么必须最后声明varargs?

这就是JAVA的编写方式。我能想到的合理解释是保持括号()的常用读取方向,它具有相关性:从左到右,如果我们要声明一个函数,如:

public void aFunc(String... args, String x, String y, String z)

如果我们使用三个参数调用此函数:aFunc("arg1", "arg2", "arg3"):那么我们有一个决策问题:哪个变量应该属于变量arity参数args?要知道答案,我们必须从右到左,只是颠倒括号()关联性的通常顺序。