以下是一个例子:
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?
答案 0 :(得分:5)
由于调用vaTest();
有两个合法的方法调用,编译器无法确定要使用哪一个。
为了帮助它,您可以提供所选类型的空数组:
vaTest(new int[] {});
答案 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
?要知道答案,我们必须从右到左,只是颠倒括号()
关联性的通常顺序。