文章目录
- **Java 可变参数(Varargs)使用指南**
- **1. 基本语法**
- **2. 调用方式**
- **3. 关键注意事项**
- **4. 底层实现**
- **5. 实际应用场景**
- **6. 总结**
Java 可变参数(Varargs)使用指南
1. 基本语法
- 定义方式:在方法参数中使用
类型... 参数名
,且必须是最后一个参数。 - 示例:
public void printValues(String prefix, int... numbers) {System.out.print(prefix + ": ");for (int num : numbers) {System.out.print(num + " ");}System.out.println();
}
2. 调用方式
调用方式 | 示例 | 输出 |
---|---|---|
传递多个值 | printValues("结果", 1, 2, 3); | 结果: 1 2 3 |
传递数组 | int[] arr = {4, 5, 6}; printValues("数组", arr); | 数组: 4 5 6 |
空参数 | printValues("空"); | 空: (无数字) |
3. 关键注意事项
- 参数位置
- 可变参数必须为最后一个参数,否则编译错误。
- ❌ 错误示例:
public void errorExample(int... nums, String str) {} // 编译错误
- 方法重载优先级
- 固定参数方法优先于可变参数方法:
void test(int a, int b) {} // 优先调用
void test(int... nums) {} // 参数不匹配时调用
* `test(1, 2)` → 调用第一个方法。 * `test(1)` → 调用第二个方法。
- 避免重载歧义
- 两个可变参数方法会导致编译错误:
void test(int... nums) {}
void test(String... strs) {}
test(); // 编译错误:无法确定调用哪个方法
- 处理
null
值
- 情况 1:可变参数本身为
<font style="color:rgb(64, 64, 64);">null</font>
printValues(null, 1, 2); // 第一个参数是 prefix,被赋值为 null
- **<font style="color:rgb(64, 64, 64);">风险</font>**<font style="color:rgb(64, 64, 64);">:若方法内直接使用 </font>`<font style="color:rgb(64, 64, 64);">prefix</font>`<font style="color:rgb(64, 64, 64);">(如 </font>`<font style="color:rgb(64, 64, 64);">prefix.length()</font>`<font style="color:rgb(64, 64, 64);">),会抛出 </font>`<font style="color:rgb(64, 64, 64);">NullPointerException</font>`<font style="color:rgb(64, 64, 64);">。</font>
- 情况 2:可变参数数组为
<font style="color:rgb(64, 64, 64);">null</font>
int[] nums = null;
printValues("前缀", nums); // 可变参数 numbers 接收 null
- **<font style="color:rgb(64, 64, 64);">风险</font>**<font style="color:rgb(64, 64, 64);">:遍历 </font>`<font style="color:rgb(64, 64, 64);">numbers</font>`<font style="color:rgb(64, 64, 64);"> 时(如 </font>`<font style="color:rgb(64, 64, 64);">for (int num : numbers)</font>`<font style="color:rgb(64, 64, 64);">),会抛出 </font>`<font style="color:rgb(64, 64, 64);">NullPointerException</font>`<font style="color:rgb(64, 64, 64);">。</font>
- 直接传递
null
可能引发NullPointerException
,建议检查:
prefix = (prefix == null) ? "默认前缀" : prefix;
//或者
if (numbers == null) {numbers = new int[0]; // 替换为空数组}
4. 底层实现
- 可变参数在编译后会转换为数组:
// 源码
void sum(int... nums) {}// 编译后等价于
void sum(int[] nums) {}
5. 实际应用场景
- 日志工具类
public class Logger {public static void log(String format, Object... args) {format = format == null ? "[无消息]" : format;args = args == null ? new Object[0] : args;String message = String.format(format, args);System.out.println(message);}
}// 调用示例
Logger.log(null, "Alice"); // 输出: [无消息]
Logger.log("用户: %s", null); // 输出: 用户: null
Logger.log("数据: %d", (Object)null); // 输出: 数据: null
- 数学计算
public static int max(int... numbers) {if (numbers == null || numbers.length == 0) {throw new IllegalArgumentException("参数不能为null或空");}int max = numbers[0];for (int num : numbers) {if (num > max) max = num;}return max;
}// 调用示例
max(1, 3, 2); // 正常返回 3
max(null); // 抛出 IllegalArgumentException
6. 总结
优点 | 注意事项 | 适用场景 |
---|---|---|
简化调用,参数数量灵活 | 必须作为最后一个参数 | 日志、工具方法、参数数量不确定时 |
代码更简洁 | 避免重载歧义 | 如 String.format() 、集合操作 |
兼容数组传参 | 处理 null 值防崩溃 |
核心原则:
- 可变参数提供灵活性,但需谨慎设计方法签名以避免冲突。
- 适合同类型参数数量不确定的场景。
参考:博客园