本文内容大多基于官方文档和网上前辈经验总结,经过个人实践加以整理积累,仅供参考。
Java 1.5 引入了 Varargs 机制(Variable number of arguments,可变参数)
可变参数特点:
1 一个方法中只能定义一个可变参数
2 如果方法中包含多个参数,可变参数必须位于参数列表最后
3 调用可变参数的方法时,编译器将可变参数隐式转化为一个数组,在方法中以数组方式访问可变参数,如
public static void method(String... params) {
// method body
}
编译器会转化为以下形式,并在编译好的 class
文件中打上标记,表明这是个可变参数方法
public static void method(String[] params) {
// method body
}
因为编译器将可变参数隐式转化为一个数组,所以不允许有相同类型数组的重载方法,在 Eclipse 中定义以下两个方法:
可以看到 Eclipse 的报错信息:
Duplicate method method(String...)
Duplicate method method(String[])
定义可变参数方法实例
public static int sum(int... nums) {
int result = 0;
for (int num : nums) {
result += num;
}
return result;
}
调用可变参数方法实例
1 传递多个参数
@Test
public void test() {
assertEquals(10, sum(1, 2, 3, 4));
}
2 传递数组参数
@Test
public void test() {
assertEquals(10, sum(new int[] {1, 2, 3, 4}));
}
3 不传参
@Test
public void test() {
assertEquals(0, sum());
}
4 传递空数组
@Test
public void test() {
assertEquals(0, sum(new int[] {}));
}
转发可变实参
public static int sum(int... nums) {
int result = 0;
for (int num : nums) {
result += num;
}
return result;
}
public static int multiple(int... nums) {
int result = 1;
for (int num : nums) {
result *= num;
}
return result;
}
public static int arithmetic(int... nums) {
return multiple(nums) - sum(nums);
}
@Test
public void test() {
assertEquals(14, arithmetic(1, 2, 3, 4));
}
可变参数方法的重载
public static int arithmetic(int... nums) {
int result = 0;
for (int num : nums) {
result += num;
}
return result;
}
public static int arithmetic(int num1, int num2) {
return num1 - num2;
}
@Test
public void test() {
assertEquals(1, arithmetic(3, 2));
}
从以上方法中可以看出,arithmetic
方法有两种重载形式,一种接受可变的 int
类型参数,将这些参数的总和返回,另一种接受固定的两个 int
类型参数,将这两个参数的差返回,两种方法的计算逻辑明显是不同的,从测试代码可以看出,在调用重载方法传递两个 int
类型参数时执行的是固定参数的方法,尽管看起来也适用可变参数方法,但是编译器对不同的方法赋予了不同的优先级,如果优先级相同则无法判断到底该调用哪个方法,对于可变参数方法的重载,编译器判断优先级的原则是:固定参数的方法优先于可变参数的方法
重载可变参数方法带来的问题
1 实参类型和可变参数类型相同
Eclipse 报错,错误信息:
The method arithmetic(int[]) is ambiguous
2 基本类型与其包装类
Eclipse 报同样错误信息:
The method arithmetic(int[]) is ambiguous