Java 5 引入的可變參數允許方法接收「同類型、任意個數」的參數,本質是編譯器自動將實參打包為數組傳遞的語法糖。
// 可變參數定義
public int sum(int... numbers) { ... }
// 編譯器視角等價於
public int sum(int[] numbers) { ... }
關鍵點:... 只能出現在參數列表最後一個位置,且每個方法最多只能有一個可變參數。
// 1. 傳遞數組(傳統方式)
sum(new int[]{1, 2, 3});
// 2. 直接列舉參數(語法糖核心優勢)
sum(); // 0 個參數 → 空數組
sum(1); // 1 個參數 → 長度1數組
sum(1, 2); // 2 個參數
sum(1, 2, 3); // 3 個參數
// 編譯器自動轉為:sum(new int[]{1,2,3})
| 階段 | 源碼 | 編譯後字節碼邏輯 |
|---|---|---|
| 方法定義 | void foo(int... args) | void foo(int[] args) |
| 方法調用 | foo(1,2,3) | foo(new int[]{1,2,3}) |
| 方法調用 | foo() | foo(new int[0]) |
運行時完全無感知,JVM 看到的永遠是 int[] 參數。
void foo(int... a, String b) ❌ 編譯報錯。void foo(int... a, int... b) ❌void print(int i) { ... }
void print(int... arr) { ... }
print(1); // 匹配 print(int) —— 固定參數優先
print(1, 2); // 匹配 print(int...) —— 唯一可行
<T> void foo(T... args) 在調用時可能產生「unchecked generic array creation」警告,需加 @SafeVarargs 抑制(JDK 7+)。// ✅ 推薦:工具類聚合操作
public static String join(String delimiter, String... parts) {
return String.join(delimiter, parts);
}
// ✅ 推薦:日誌/埋點方法
log.info("userId={}, action={}, extras={}", userId, action, (Object[]) extras);
// ❌ 避免:作為普通業務參數濫用,導致調用端不明確
// 例如:saveUser(String name, String... phones) —— 不如 List 清晰
可變參數是「數組參數的語法糖」,核心價值在於調用端極簡。掌握其編譯原理、重載優先級、泛型堆污染等細節,才能在 API 設計中游刃有餘,避免踩坑。