Java可变参数
在jdk5之前,可能我们要通过这样的方式来实现可变参数的方法:
package www.com.thinkInJava.initializationCleanup; 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(23), 23.2f, "sdfdsf", new Double(23.234), new A()}); } } class A{}
通过Object[]数组来实现。
输出如下:
但在jdk5之后,Java终于有可变参数这个特征了。
语法类似于static void printArray(Object... args)
package www.com.thinkInJava.initializationCleanup; 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 Integer(32), 23.f, "sfsdf", new String("helosdfakl"), 234, new A()); printArray((Object[])new Integer[]{12, 23, 345, 456, new Integer(666)}); printArray(); } } class A{}
输出如下:
main函数里的第一句调用可见,这个可变参数的原理应该类似于我们之前的Object[]的方法,因为我们传进去的是普通的不同的参数,而却可以用array的foreach来遍历元素,说明应该是自动将一系列元素转换成了数组;
main函数的第二句调用可见,还可以直接传一个数组Object的array进去。(这里我们将Integer引用的数组转换成了Object的,同时数组的定义里面也用了autoboxing,即把普通的int自动转换成对应的Integer对象。)
main函数的第三句调用可见,对于可变参数的方法,可以什么都不传过去。
下面一个例子证明了,可变参数确实是把参数转换成了数组的形式:
package www.com.thinkInJava.initializationCleanup; public class VarargType { static void f(Character... args) { System.out.print(args.getClass()); System.out.println(" length " + args.length); } static void g(int... args) { System.out.print(args.getClass()); System.out.println(" length " + args.length); } public static void main(String[] args) { f('a'); f(); g(1); g(); System.out.println("int[]: " + new int[0].getClass()); } }
输出:
这里,class的描述,有个“[”开头,表明这个class是个数组,然后中括号后面紧跟着的就是这个数组的数据类型,像这里紧跟着的I表明这是个基本数据类型int的数组。
main函数里面最后的一行代码证明了这个过程,直接输出了一个int数组的getClass,输出和上面的一样,证明可变参数确实是把元素转换成数组。
方法的重载overload也是可以用可变参数的,但可能会使方法变得很复杂,建议小心使用,这里也给个例子:
package www.com.thinkInJava.initializationCleanup; public class OverloadingVarargs { static void f(Character... args) { System.out.print("first"); for (Character c : args) System.out.print(" " + c); System.out.println(); } static void f(Integer... args) { System.out.print("second"); for (Integer i : args) System.out.print(" " + i); System.out.println(); } static void f(Long... args) { System.out.println("third"); } public static void main(String[] args) { f('a', 'b', 'c'); f(1); f(2, 1); f(0); f(0L); // ! f(); // Won’t compile -- ambiguous } }
输出结果:
这里看到,不能调用没有参数的f()了,因为编译器无法辨别是哪个方法。这个无参数的方法调用连编译都无法通过。