是瓦拉格斯 :)
varargs是可变长度参数的缩写,它允许方法接受可变数量的参数(0或更多)。使用varargs,创建需要使用可变数量参数的方法变得非常简单。在Java 5中添加了变量参数的特性。
varargs语法
在数据类型之后,一个vararg由三个省略号(三个点)组成,其一般形式是return_type method_name(data_type ... variableName){}
对静脉曲张的需求
在Java 5之前,如果需要可变数量的参数,有两种方法来处理
如果一个方法可以接受的参数的最大值很小且已知,则可以创建该方法的重载版本。如果方法可以使用的参数的最大数量很大或/且未知,则方法是将这些参数放入数组中,并将它们传递给以数组为参数的方法。这两种方法都很容易出错-每次都要构造一个参数数组,而且很难维护-因为添加新的参数可能会导致编写一个新的重载方法。
静脉曲张的优点
提供了一个简单得多的选择。减少代码,因为不需要编写重载的方法。
静脉曲张的例子public class VarargsExample {
public void displayData(String ... values){
System.out.println("Number of arguments passed " + values.length);
for(String s : values){
System.out.println(s + " ");
}
}
public static void main(String[] args) {
VarargsExample vObj = new VarargsExample();
// four args
vObj.displayData("var", "args", "are", "passed");
//three args
vObj.displayData("Three", "args", "passed");
// no-arg
vObj.displayData();
}}OutputNumber of arguments passed 4var
args
are
passed
Number of arguments passed 3Three args
passed
Number of arguments passed 0
从程序中可以看出,这里使用长度来查找传递给该方法的参数。这是可能的,因为varargs被隐式地作为数组传递。任何作为varargs传递的参数都存储在一个数组中,该数组通过给varargs的名称来引用。在这个程序中,数组名是值。还请注意,方法是以不同数量的参数调用的,首先调用四个参数,然后调用三个参数,然后调用零参数。所有这些调用都由使用varargs的相同方法处理。
带静脉曲张的限制
可以在方法中使用varargs参数的其他参数,但是在这种情况下,varargs参数必须是该方法声明的最后一个参数。void displayValues(int a, int b, int … values) // OK
void displayValues(int a, int b, int … values, int c) // compiler error
varargs的另一个限制是必须只有一个varargs参数。void displayValues(int a, int b, int … values, int … moreValues) // Compiler error
超负荷varargs方法
可以重载接受varargs参数的方法。Varargs方法可以通过-
其vararg参数的类型可能不同。通过添加其他参数。超负荷varargs方法实例public class OverloadingVarargsExp {
// Method which has string vararg parameter
public void displayData(String ... values){
System.out.println("Number of arguments passed " + values.length);
for(String s : values){
System.out.println(s + " ");
}
}
// Method which has int vararg parameter
public void displayData(int ... values){
System.out.println("Number of arguments passed " + values.length);
for(int i : values){
System.out.println(i + " ");
}
}
// Method with int vararg and one more string parameter
public void displayData(String a, int ... values){
System.out.println(" a " + a);
System.out.println("Number of arguments passed " + values.length);
for(int i : values){
System.out.println(i + " ");
}
}
public static void main(String[] args) {
OverloadingVarargsExp vObj = new OverloadingVarargsExp();
// four string args
vObj.displayData("var", "args", "are", "passed");
// two int args
vObj.displayData(10, 20);
// One String param and two int args
vObj.displayData("Test", 20, 30);
}}OutputNumber of arguments passed 4var
args
are
passed
Number of arguments passed 210 20
a TestNumber of arguments passed 220 30
Varargs与超载歧义
在某些情况下,当我们有重载varargs方法时,调用可能是模棱两可的。让我们看看一个例子public class OverloadingVarargsExp {
// Method which has string vararg parameter
public void displayData(String ... values){
System.out.println("Number of arguments passed " + values.length);
for(String s : values){
System.out.println(s + " ");
}
}
// Method which has int vararg parameter
public void displayData(int ... values){
System.out.println("Number of arguments passed " + values.length);
for(int i : values){
System.out.println(i + " ");
}
}
public static void main(String[] args) {
OverloadingVarargsExp vObj = new OverloadingVarargsExp();
// four string args
vObj.displayData("var", "args", "are", "passed");
// two int args
vObj.displayData(10, 20);
// This call is ambiguous
vObj.displayData();
}}
在这个程序中,当我们在没有任何参数的情况下调用Displaydata()方法时,它会抛出错误,因为编译器不确定此方法调用是否用于displayData(String ... values)或displayData(int ... values)
如果我们有重载方法,其中一个方法具有vararg方法的一种类型,另一种方法有一个参数,vararg参数的类型相同,那么我们也有歧义-作为Exp-displayData(int ... values)和displayData(int a, int ... values)
这两个重载的方法总是有歧义的。