Java 5 (JDK 1.5) 引入的可變參數特性,允許方法接受同類型的任意數量參數(含零個),語法為 型別... 參數名:
public class VarargsDemo {
public static void print(String... args) {
for (String s : args) {
System.out.println(s);
}
}
public static void main(String[] args) {
print("A"); // 1 個參數
print("A", "B"); // 2 個參數
print("A", "B", "C"); // 3 個參數
print(); // 0 個參數(合法)
}
}
編譯器將可變參數視為陣列處理。呼叫端會自動建立陣列並填入引數:
print("A") → print(new String[]{"A"})print("A", "B") → print(new String[]{"A", "B"})print() → print(new String[]{}) (空陣列)方法內部透過 for (String s : args) 遍歷陣列,與操作一般陣列無異。
適用於「參數數量不固定但類型相同」的場景。JDK 經典案例:
String.format(String format, Object... args)PrintStream.printf(String format, Object... args)Arrays.asList(T... a)Collections.addAll(Collection<T> c, T... elements)// 合法
void method(int fixed, String... varargs) { }
// 編譯錯誤:可變參數不在最後
void method(String... varargs, int fixed) { }
// 編譯錯誤:多個可變參數
void method(String... a, int... b) { }
// 典型模式:前置固定參數 + 可變參數
public void log(String level, String message, Object... params) {
System.out.printf("[%s] " + message + "%n", level, params);
}
// 呼叫
log("INFO", "User {0} logged in from {1}", "Alice", "192.168.1.1");
String[] arr = {"A", "B", "C"};
print(arr); // 直接傳陣列
print("X", arr); // 錯誤!會被視為兩個參數:String 和 String[]
print("X", (Object[]) arr); // 強制轉型為 Object[] 避免歧義
void foo(Object... args) { }
void foo(String... args) { } // 編譯通過,但呼叫 foo("A") 會報錯誤:模稜兩可
List.of() 等不可變集合工廠方法替代部分場景可變參數是語法糖,本質是陣列自動建立與傳遞。它大幅簡化了 API 設計,但需注意:只能有一個、必須在最後、避免多載衝突、留意效能開銷。善用它能讓 API 更靈活易用。