方法重載 是指同一類中定義多個同名方法,但參數列表不同 (類型、個數、順序)。編譯器根據調用時的實參類型靜態綁定到具體方法,屬於靜態多態 (編譯期多態)。
| 規則 | 說明 | 示例 |
|---|---|---|
| 方法名相同 | 必須完全一致 | print(int) / print(String) |
| 參數列表不同 | 類型、個數、順序任意一項不同即可 | add(int, int) vs add(int, int, int)foo(String, int) vs foo(int, String) |
| 返回類型、修飾符、拋出異常 可相同可不同 | 不能僅靠這些區分重載 | ❌ int foo() / String foo() (編譯錯誤) |
public class OverloadDemo {
// 1. 參數個數不同
public void print(String msg) { System.out.println(msg); }
public void print(String msg, int times) {
for (int i=0;i
編譯器按以下順序嘗試匹配:
byte/short/char → int → long → float → doubleint ↔ IntegerString... 匹配 0~N 個 String 或 String[]
void test(int i) { System.out.println("int"); }
void test(Integer i) { System.out.println("Integer"); }
void test(long l) { System.out.println("long"); }
void test(Number n) { System.out.println("Number"); }
void test(Object o) { System.out.println("Object"); }
void test(int... arr) { System.out.println("int..."); }
// 調用測試
test(10); // 1. 精確匹配 int
test((short)1); // 2. short 提升為 int
test(10L); // 3. 精確匹配 long
test(new Integer(1)); // 3. 精確匹配 Integer (裝箱優於 long 提升)
test(1.0f); // 4. float 提升為 double (若無 double 則 Object)
test("str"); // 5. 精確匹配 String (Object 子類)
test(); // 6. 可變參數匹配空參
test(1,2,3); // 6. 可變參數匹配多參
// ❌ 編譯錯誤: 擦除後都是 List
void foo(int... a) { }
void foo(int[] a) { } // ❌ 編譯錯誤: 可變參數本質就是數組
// 調用二義性
foo(new int[]{1,2}); // 匹配哪個?編譯器報錯
void bar(Long l) { }
void bar(int i) { }
bar(10); // 調用 int (基本類型優先)
bar((long)10); // 調用 long
bar(new Long(10)); // 調用 Long
// bar(null); // ❌ 二義性: 既可匹配 Long 也可匹配 int (null 可賦值給任意引用)
interface IntFunc { int apply(int x); }
interface LongFunc { long apply(long x); }
void exec(IntFunc f) { }
void exec(LongFunc f) { }
// exec(x -> x * 2); // ❌ 二義性: 無法推斷目標類型
exec((IntFunc) x -> x * 2); // ✅ 顯式指定
| 維度 | 重載 | 重寫 |
|---|---|---|
| 位置 | 同一類 | 父子類 |
| 方法名 | 相同 | 相同 |
| 參數列表 | 必須不同 | 必須相同 |
| 返回類型 | 任意 | 兼容 (协變) |
| 訪問修飾符 | 任意 | 不能更嚴格 |
| 拋出異常 | 任意 | 不能更寬泛 |
| 綁定時間 | 編譯期 (靜態) | 運行期 (動態) |
| 多態類型 | 靜態多態 | 動態多態 |
print、sum、convert)。foo(int) 和 foo(Integer)、foo(long);不混用可變參數與數組重載。append(String)、append(int)、append(long)) 避免自動提升/裝箱開銷。方法重載是 Java 提供同名不同參便利性的語法糖,本質是編譯期靜態綁定。掌握 參數列表差異規則、解析優先級、泛型擦除/可變參數/裝箱二義性 等核心機制,能設計出直觀、高效、無驚喜的 API。記住:重載看參數,重寫看繼承;重載是編譯期,重寫是運行期。