在本文中,您将借助示例来学习Java中的可变参数(Varargs)。您还将学习何时使用varargs,何时不使用它们。
假设您正在创建Java方法。但是,您不确定您的方法将接受多少个参数。为了解决这个问题,Java 1.5引入了varargs。
Varargs是变量参数的缩写。 在Java中,方法的参数可以接受任意数量的值。 可以接受可变数量的值的该参数称为varargs。
实现 varargs 的语法如下:
accessModifier methodName(datatype… arg) { // 方法主体 }
为了定义vararg,在方法的形参中使用……(三个点)。
接受可变数量参数的方法称为可变数量方法,或简称为varargs方法。
首先,让我们看一下不使用varargs的示例:
class NoVararg { public int sumNumber(int a, int b){ return a+b; } public int sumNumber(int a, int b, int c){ return a+b+c; } public static void main( String[] args ) { NoVararg obj = new NoVararg(); System.out.println(obj.sumNumber(1, 2)); System.out.println(obj.sumNumber(1, 2, 3)); } }
当您运行该程序时,输出将是:
3 6
正如您看到的,必须重载sumNumber()方法才能使其适用于3个参数。
如果用户要添加5个数字或10或100,该怎么办?
使用varargs可以以一种简洁的方式处理这一问题。让我们看一个代码示例:
class VarargExample { public int sumNumber(int ... args){ System.out.println("参数长度: " + args.length); int sum = 0; for(int x: args){ sum += x; } return sum; } public static void main( String[] args ) { VarargExample ex = new VarargExample(); int sum2 = ex.sumNumber(2, 4); System.out.println("sum2 = " + sum2); int sum3 = ex.sumNumber(1, 3, 5); System.out.println("sum3 = " + sum3); int sum4 = ex.sumNumber(1, 3, 5, 7); System.out.println("sum4 = " + sum4); } }
运行该程序时,输出为:
参数长度: 2 sum2 = 6 参数长度: 3 sum3 = 9 参数长度: 4 sum4 = 16
在这里,sumNumber()方法返回传递给它的int参数的总和(与传递的参数数量无关)。
正如您看到的,varargs在某些情况下非常有用。但是,如果您确定传递给方法的参数数量,请改用方法重载。例如,如果您确定sumNumber()方法仅用于计算2个或3个参数的总和,请像第一个示例一样使用重载。
让我们再举一个实例。Java库中定义的format()方法接受varargs。在JDK中,format()方法定义如下:
public static String format(Locale l, String format, Object... args) { // body }
class Company { public static void main(String[] args) { String siteName = "(cainiaojc.com)"; int empCount = 6; String type = "教程网站"; System.out.println( String.format( "Site Name : %s, Emp Count: %d Type: %s", siteName, empCount, type ) ); } }
运行该程序时,输出为:
Site Name : (cainiaojc.com), Emp Count: 6 Type: 教程网站
让我们看以下伪代码:
public int sumNumber(int ... nums) { // 方法主体 }
... 语法告诉Java编译器可以使用零个或多个参数来调用该方法。 结果,nums变量被隐式声明为int []类型的数组。 因此,在方法内部,使用数组语法访问nums变量。
如果没有参数,则长度nums为0。
与典型方法类似,您可以重载vararg方法。
class VarargOverload { private void test(int ... args){ int sum = 0; for (int i: args) { sum += i; } System.out.println("sum = " + sum); } private void test(boolean p, String ... args){ boolean negate = !p; System.out.println("negate = " + negate); System.out.println("args.length = "+ args.length); } public static void main( String[] args ) { VarargOverload obj = new VarargOverload(); obj.test(1, 2, 3); obj.test(true, "hello", "world"); } }
运行该程序时,输出为:
sum = 6 negate = false args.length = 2
在上面的程序中,test()方法通过更改其接受的参数数量而重载。
这是使用Java Varargs时应记住的几件事:
1.在定义方法签名时,请务必保留最后varargs。
变量参数必须是传递给方法的最后一个参数。考虑一下,您调用了如下doSomething()方法:
doSomething(1, 2, 3, 4);
并且,您的doSomething()方法定义为:
//错误的方法声明 public void doSomething(int ... nums, int p){ // method body }
在这种情况下,编译器无法确定传递给nums的参数数量。
但是,如果将方法定义为:
public void doSomething(int p, int ... nums) { // method body }
Java编译器将第一个参数分配给 p,其余int参数分配给 nums。
2.一种方法只能有一个varargs参数。
例如,此方法声明不正确:
int doSomething(int p, float ... floatNums, double ... doubleNums) { // code }
让我们看一下这样的重载test()方法:
class Demo { static void test(int ... vargs) { // method body } static void test(int n, int ... vargs) { // method body } }
在上面的程序中,即使您尝试调用test()方法,即使test()方法已重载并且接受不同数量的参数,编译器也会感到困惑。
编译器不知道调用哪个方法。编译器可能会认为,您正在尝试test(int ... vargs)使用一个varargs参数进行调用。同样,编译器可能会认为,您正在尝试test(int n, int ... vargs)使用传递给第一个参数的参数调用,而第二个参数为空。
由于存在两种可能性,因此会引起歧义。因此,有时您可能需要使用两个不同的方法名称,而不是重载varargs方法。