Java 可变长参数本质是语法糖
可以理解为编译器帮我们把参数实例化为数组, 再传入方法
/**
* 可变长参数
*/
@Test
public void testVarargs() {
// 允许方法什么也不传, 那么编译器会帮我们实例化 new int[0] 传入
foo();
// 传入 null, 则编译器会把该可变参数赋值为 null, 即数组为 null
foo(null);
// 传入 1, 2, 3, 4
// 编译器会帮我们实例化 new int[]{1, 2, 3, 4} 传入方法
foo(1, 2, 3, 4);
// 等效于 foo(1, 2, 3, 4);
foo(new int[]{1, 2, 3, 4});
}
private void foo(int... arr) {
if (arr == null) {
return;
}
for (int value : arr) {
System.out.println(value);
}
}
javap 查看字节码, 可以看到方法声明的形参其实是数组
其他细节:
可变长参数固定放在形参列表最后一位
如果有重载方法, 那么优先选择不带可变长参数的方法
/**
* 可变长参数固定放在形参列表最后一位
* 如果有重载方法, 那么优先选择不带可变长参数的方法
*/
@Test
public void testOverload() {
// 会调用 foo2(String str)
foo2("abc");
// 会调用 foo2(String str, int... arr)
foo2("abc", 1, 2, 3, 4);
}
private void foo2(String str, int... arr) {
System.out.println("foo2(String str, int... arr)");
}
private void foo2(String str) {
System.out.println("foo2(String str)");
}
总结:
可变长参数是 Java 语法糖
- 固定放在方法形参最末尾
- 允许不传值, 则默认初始化 0 长度的数组
- 允许传 null, 则赋值整个数组为 null
- 允许传不定长参数, 会帮我们自动实例化为数组
- 允许传数组, 则方法形参原样接收该数组
- 当有重载方法时, 优先选择不带可变长参数的方法