本文所有用例仅在JDK1.8下测试通过
可变参数列表
Java SE5中新增了"可变参数列表"特性, 使用它可以产生可变的参数列表
什么是可变参数列表
通常我们写的方法的参数个数都是固定的, 当在一些需要不定参数个数 (0个或多个参数)
时就不是很方便(C语言通过stdarg.h头文件提供对可变参数的支持), 以往的程序员多是通过传入数组来实现, 例如下面所示:
public class Demo {
public static void main(String[] args){
System.out.println(max(new int[]{2,1,3,6,5}));
}
public static int max(int[] nums){
int max = nums[0];
for(int i = 0; i < nums.length; i++){
if(nums[i] > max)
max = nums[i];
}
return max;
}
}
自SE5以后, 我们可以在 类型名
后跟上 ...
来表示可变参数列表, 实际上它还是一个 数组
类型, 但是这样我们调用此方法时既可用上面那种方式传入参数, 也可以用更简便的方法传参, 如下:
public class Demo {
public static void main(String[] args){
//System.out.println(max(new int[]{2,1,3,6,5}));同样可以通过这样调用
System.out.println(max(2,1,3,6,5));
}
public static int max(int... nums){
System.out.println(nums.getClass());
int max = nums[0];
for(int i = 0; i < nums.length; i++){
if(nums[i] > max)
max = nums[i];
}
return max;
}
}
输出:
class [I
6
[
表示是一个数组, I
表示int类型
可变参数方法重载
考虑这样一个问题, 如下所示
public class Demo {
public static void main(String[] args){
//System.out.println(overload()); 无法编译
System.out.println(overload(1));
System.out.println(overload("1"));
}
public static String overload(int... a){
return "method: int";
}
public static String overload(String... a){
return "method: String";
}
}
输出
method: int
method: String
和我们预期一致, 当不传入参数时编译器不知道应该调用哪一个参数, 若传入参数则调用与传入参数相匹配的方法
但, 考虑如下代码
public class Demo {
public static void main(String[] args){
System.out.println(overload());
}
public static String overload(char... a){
return "method: char";
}
public static String overload(short... a){
return "method: short";
}
public static String overload(int... a){
return "method: int";
}
public static String overload(long... a){
return "method: long";
}
public static String overload(double... a){
return "method: double";
}
}
编译会提示
Error:(9, 28) java: 对overload的引用不明确
com.test.demo.Demo 中的方法 overload(char...) 和 com.test.demo.Demo 中的方法 overload(short...) 都匹配
根据提示我们可以看到, 当重载基本类型时, 若同时有char和short类型的重载, 此时调用重载的可变参数方法且不传入任何参数, 编译器会匹配两个方法, 即编译错误不知道该调用哪一个方法
当我们把上面的代码片段的 public static String overload(char... a){
或 public static String overload(short... a){
任选一个注释掉后, 编译器会调用参数为 int...
的方法, 若把 int...
注释后又会调用 long...
依次类推
其他
若同时定义了仅有可变参数的方法和无法的方法, 编译器会调用 最精确
的那个方法, 其他场景下同样.
总结
在对仅有可变参数的方法进行重载时, 调用时不传参并不一定会编译错误或运行异常