java的varargs机制

来源:互联网 发布:数据库关系模式的定义 编辑:程序博客网 时间:2024/06/05 13:47

偶然看到有人把main方法的方法签名这样写:public static void main(String... args),成功引起我的注意哈哈,赶紧查了一下,原来“类型...“或者“类型 ...”这两种形式的参数代表个数可变的参数(>=0)。这种机制在jdk1.5出现,Varargs”是“variable number of arguments”的意思,它可以定义能和多个实参相匹配的形参。这种机制出现之前,我们只能用数组来接收个数不确定的实参,比如main方法,jdk1.5之前只能用String[] args来接收。


使用方法

1.在数据类型和变量名之间加上连续的3个英文句号;
2.每个方法参数列表中只能有一个varargs参数;
3.如果方法中有多个参数,那么varargs参数必须放在最后。
// 3个英文句号与参数名之间有一个空格,推荐这种写法,与数组一样int[] intspublic static void userVarargs(int... ints) {}// 3个英文句号与参数名之间没有空格public static void userVarargs(double...doubles) {}// The variable argument type int of the method varargsAtLast must be the last parameterpublic static void varargsAtLast(int... ints, String a) {}// 只能包含一个varargs,否则前面的varargs不能位于最后一个参数位置public static void varargsAtLast(int... ints, String... strings) {}
int...的本质是int[]
编译器会在背地里把这最后一个形参转化为一个数组形参,并在编译出的class文件里作上一个记号,表明这是个实参个数可变的方法。所以如果我们有两个方法,一个参数为int[] ints,另一参数为int... ints,这样编译不通过,因为在编译器看来他们是一样的。
public static void sameWithArray(int[] ints) {}  // Duplicate method sameWithArray(int[])public static void sameWithArray(int... ints) {}  // Duplicate method sameWithArray(int[])
不传参数

我们打印varargs参数的长度—ints.length,输出0,并且这也印证了它本质是一个数组。

public static void zeroArg(int... ints) {System.out.println(ints.length);}public static void main(String... args) {zeroArg();  // 0}

优先调用参数个数确定的方法

我们先看下面的代码
如果我们调用了带有Varargs参数的方法,传入的实参个数和类型与某个非Varargs参数的方法一样,那么编译器优先选择参数确定的那个方法。
public static void callWho(int a, int b) {System.out.println("the number of arguments is explicit");}public static void callWho(int... ints) {System.out.println("the number of arguments is variable");}public static void main(String... args) {callWho(1, 2);  // the number of arguments is explicit}

与数组的比较

方法调用:Varargs参数可以直接传0或多个参数,而数组参数得先把实参包装进一个数组后再传进方法里,可以看出Varargs参数方法比较方便;参数使用:参数使用基本一样,Varargs参数在方法里使用的形式和数组一样


Varargs参数遇上泛型

造成这个现象的原因在于J2SE 1.5中的泛型机制的一个内在约束——标识符代表的类型不能创建这一类型的实例。比如不能由泛型T创建T[]。不过,传统的“用数组包裹”的做法,并不受这个约束的限制。


自动装/拆箱带来的问题

若存在方法签名除了int和Integer这个不同,其它都一样,也会因为自动装/拆葙而使编译器无法区分2个方法
public static void autoBoxing(int... args) {}public static void autoBoxing(Integer... args) {}public static void main(String... args) {autoBoxing(1, 2, 3);  // The method autoBoxing(int[]) is ambiguous}
缺点
可以传多个数组参数,但每个方法中只能定义一个varargs参数。
原创粉丝点击