可变参数(varargs)
可变参数列表(variable argument lists)包含不确定的参数数量和参数类型,是一种更加灵活的语法
既然所有的类都继承自Object,那么可以新建一个参数是Object数组的方法,如:
//: initialization/VarArgs.java
// Using array syntax to create variable argument lists.
class A {}
public class VarArgs {
static void printArray(Object[] args) {
for(Object obj : args)
System.out.print(obj + " ");
System.out.println();
}
public static void main(String[] args) {
printArray(new Object[]{ new Integer(47), new Float(3.14), new Double(11.11) });
printArray(new Object[]{"one", "two", "three" });
printArray(new Object[]{new A(), new A(), new A()});
printArray(); // Empty list is OK
}
}
/* Output: (Sample)
47 3.14 11.11
one two three
A@1a46e30 A@3e25a5 A@19821f
注意:如果类中没有定义toString()方法,则会输出类名加对象的地址
有了可变参数,就不用写明数组语法,编译器会自动填充。
注意:传空参数到可变参数中也是可行的。当有可选的尾随参数(optional trailing arguments)时,这会有所帮助,见下面的例子:
//:initialization/OptionalTrailingArguments.java
public class OptionalTrailingArguments {
static void f(int required, String... trailing) {
System.out.print("required: " + required + " ");
for(String s : trailing)
System.out.print(s + " ");
System.out.println();
}
public static void main(String[] args) {
f(1, "one");
f(2, "two", "three");
f(0);
}
}
/* Output:
required: 1 one
required: 2 two three
required: 0
*///:~
从上例中可以看到可变参数中也可以使用其他类型,如String,而非都是Object.
可变参数可以使用任何类型包括基本类型。
可变参数适用自动装箱(autoboxing)
//: initialization/AutoboxingVarargs.java
public class AutoboxingVarargs {
public static void f(Integer... args) {
for(Integer i : args)
System.out.print(i + " ");
System.out.println();
}
public static void main(String[] args) {
f(new Integer(1), new Integer(2));
f(4, 5, 6, 7, 8, 9);
f(10, new Integer(11), 12);
}
}
/* Output:
1 2
4 5 6 7 8 9
10 11 12
*///:~
注意上例中基本类型和包装类混合使用,自动装箱会将int打包为Integer
可变参数会让方法重载变得复杂,
例如:
static void f(Character… args){…} 和 static void f(Integer… args){…}
有参数时编译器可以根据参数调用相应的方法,但是如果是空方法f(),编译器无法分辨是哪个方法,从而无法编译。
为解决这个问题,要给方法中加入非可变参数的参数(non-vararg argument),如:
//: initialization/OverloadingVarargs3.java
public class OverloadingVarargs3 {
static void f(float i, Character... args) {
System.out.println("first");
}
static void f(char c, Character... args) {
System.out.println("second");
}
public static void main(String[] args) {
f(1, ‘a’);
f(‘a’, ‘b’);
}
}
/* Output:
first
second
*///:~
记住重载方法时,慎用可变参数