首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 方法重載完整指南:規則、構造器重載、返回值陷阱與最佳實踐

     編輯:Java 相關知識

什麼是方法重載

同一類中**方法名相同、參數列表不同** (個數、型別、順序) 的多個方法。編譯器根據**靜態綁定** (引用型別、實參型別) 決定呼叫哪個版本。

構成重載的三要素

差異點範例說明
參數個數`f()` vs `f(int a)`最常見
參數型別`f(int a)` vs `f(String s)`型別需明顯不同
參數順序`f(int a, String s)` vs `f(String s, int a)`順序不同即視為不同簽名

❌ 不構成重載的情況

  • 僅返回值不同:`void f()` / `int f()` → **編譯錯誤** `method f() is already defined`
  • 僅參數名不同:`f(int a)` / `f(int b)` → 同一簽名
  • 僅修飾符不同:`public f()` / `private f()` → 同一簽名
  • 靜態 vs 非靜態:`static void f()` / `void f()` → 同一簽名 (但可隱藏)
  • 拋出異常不同:不影響簽名

完整程式碼示範


public class OverloadDemo {

    // 1. 普通方法重載
    public void print() { System.out.println("無參"); }
    public void print(int i) { System.out.println("int: " + i); }
    public void print(String s) { System.out.println("String: " + s); }
    public void print(int i, String s) { System.out.println("int+String: " + i + s); }
    public void print(String s, int i) { System.out.println("String+int: " + s + i); } // 順序不同

    // 2. 構造器重載 (同樣規則)
    public OverloadDemo() { this(0); System.out.println("無參構造"); }
    public OverloadDemo(int i) { this(i, "def"); System.out.println("int構造: " + i); }
    public OverloadDemo(int i, String s) { System.out.println("全參構造: " + i + s); }

    // 3. 返回值不同 → 編譯錯誤 (取消註解驗證)
    // public int print() { return 1; } // Error: method print() already defined

    // 4. 可變參數重載 (優先級最低)
    public void print(int... nums) { System.out.println("可變參數: " + nums.length); }

    // 5. 泛型擦除後簽名相同 → 編譯錯誤
    // public void test(List list) {}
    // public void test(List list) {} // Error: same erasure

    public static void main(String[] args) {
        OverloadDemo demo = new OverloadDemo(); // 呼叫無參構造 → 鏈式呼叫 int → 全參
        demo.print();
        demo.print(100);
        demo.print("Hello");
        demo.print(1, "World");
        demo.print("World", 2);
        demo.print(1,2,3); // 匹配可變參數版本
    }
}

構造器重載鏈 (this 呼叫)


public class ChainDemo {
    private int x, y, z;
    public ChainDemo() { this(0); }                    // 呼叫 int 版
    public ChainDemo(int x) { this(x, 0); }            // 呼叫 int,int 版
    public ChainDemo(int x, int y) { this(x, y, 0); }  // 呼叫全參版
    public ChainDemo(int x, int y, int z) {            // 真正初始化
        this.x = x; this.y = y; this.z = z;
    }
    // 規則:this(...) 必須是構造器第一行語句
}

重載解析優先順序 (JLS 15.12.2)

  1. 精確匹配 (Exact Match) — 型別完全一致
  2. 基本型別擴大轉換 (Widening) — `int` → `long` → `float` → `double`
  3. 自動裝箱 (Boxing) — `int` → `Integer`
  4. 可變參數 — `int...` (最後才考慮)

void f(int i) {}
void f(long l) {}
void f(Integer i) {}
void f(int... i) {}

f(10);      // 1. 精確匹配 int
f(10L);     // 1. 精確匹配 long
f((short)10); // 2. 擴大 short→int
f(new Integer(10)); // 3. 裝箱 Integer
f();        // 4. 可變參數 (空陣列)

常見陷阱與最佳實踐

重載 vs 覆寫 對照

陷阱後果解決
基本型別 vs 包裝型別重載自動拆箱/裝箱導致歧義避免同時提供 `f(int)` 和 `f(Integer)`
可變參數與陣列重載`f(int[])` vs `f(int...)` 簽名相同二選一,別同時存在
泛型擦除導致衝突`f(List)` vs `f(List)`改用不同方法名或單一方法
重載過多導致可讀性下降呼叫端難判斷走哪個版本改用建構者模式、參數物件、或不同語意方法名
維度重載覆寫
發生位置同一類父子類
方法名相同相同
參數列表必須不同必須相同
返回值可不同 (但不構成重載)兼容 (协变返回)
存取修飾符無限制不能更嚴格
綁定時機編譯期 (靜態)執行期 (動態)

掌握重載規則與解析優先順序,能避免「明明有對應方法卻報錯」或「呼叫了非預期版本」的疑難雜症,也是面試高頻考點。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved