基本用法:
public class VarargsLearn {
public static void inputVarargs(String... args){
//可变参数方法
String[] a = args;
}
public static void main(String[] args) {
inputVarargs("a","2","4");
String[] inputArray = new String[]{"a","2","4"};
inputVarargs(inputArray);
}
}
使用要求:
Java语言规范有如下表述:
- 方法或构造函数的形参(如果有的话)是通过逗号分隔的参数制定的列表指定的。列表的最后一个形参是特殊的,可以是一个可变元数参数,通过类型后面的省略号来表示。
- 如果最后一个形参是类型为T的可变参数,则将其视作定义了一个T[]类型的形参。
- 可变参数方法的调用可以包含比形参更多的实参表达式。对于和可变参数之前的形参不对应的所有表达式,将会对其进行求值,并把结果存储在将传递给方法调用的数组中。
第二点中说明,实际上编译器认为创建了一个T[]类型的形参;
//编译器提示方法已经存在
public static void inputVarargs(String... args){
//可变参数方法
String[] a = args;
}
public static void inputVarargs(String[] args){
//数组参数方法
String[] a = args;
}
第三点下面举例说明:
String[] inputArray = new String[]{"a","2","4"};
inputVarargs();
inputVarargs("a","2","4");
inputVarargs(inputArray);
//反编译class代码如下,如果实参就是对应类型的数组,编译器不做处理;如果不是构造对应的类型的数组。
String[] inputArray = new String[]{"a", "2", "4"};
inputVarargs(new String[]);
inputVarargs(new String[]{"a", "2", "4"});
inputVarargs(inputArray);
java中数组也是一个对象,当出现一个object类型的可变参数时,需要注意编译器对代码做了怎样的处理,举例说明:
public static void inputObjectVarargs(Object... args){
}
public static void main(String[] args) {
String[] inputArray = new String[]{"a","2","4"};
//错误用法
//inputVarargs("a","2","4",args);
//object类型的可变参数
inputObjectVarargs("a","2","4");
inputObjectVarargs("a","2","4",inputArray);
inputObjectVarargs(inputArray);
inputObjectVarargs(new Object[]{inputArray});
}
//反编译class,代码如下
//将实参包装为object[]
inputObjectVarargs(new Object[]{"a", "2", "4"});
inputObjectVarargs(new Object[]{"a", "2", "4", inputArray});
//认为是object[]数组直接传入,入参是一个长度为3的string[]
inputObjectVarargs(inputArray);
//认为是object[]数组直接传入,入参是一个长度为1的object[],该数组中的元素是inputArray这个数组
inputObjectVarargs(new Object[]{inputArray});
与一般T[]数组参数类型的区别
如果没有可变参数,也可以通过数组参数类型的参数做到同样的事情。是否可变参数只存在java层面?
public static void inputVarargs(String... args){
String[] a = args;
}
public static void inputArrayArg(String[] args){
String[] a = args;
}
//反编译代码,可以看到class中仍然能识别出数组参数和可变参数
public static void inputVarargs(String... args) {
}
public static void inputArrayArg(String[] args) {
}
//使用idea查看两个方法字节码区别
public static transient varargs inputVarargs([Ljava/lang/String;)V
public static inputArrayArg([Ljava/lang/String;)V
//class中通过transient varargs标记一个方法是否是可变参数方法
//而两个方法的入参都是[Ljava/lang/String;即:string[]。
//解释了“将其视作定义了一个T[]类型的形参”、可变参数和相同类型数组方法提示方法已存在的问题