Java 重載方法的匹配規則-含有變長參數方法的匹配


Java 重載方法的匹配規則-含有變長參數方法的匹配

本文用一個例子來展示 含有變長參數的重載方法是如何匹配的

public class demo {

    void invoke(Object obj, Object... args) {
        System.out.println(1);
    }
    void invoke(String s, Object obj, Object... args) {
        System.out.println(2);
    }

    public static void main(String[] args) {
        demo d = new demo();
        d.invoke(null);     //1
        d.invoke(null, 1);  //2
        d.invoke(null,2,1); //2
        d.invoke(1,2,1);    //1
    }
}

重載方法的匹配規則:
——引用自《深入拆解 Java 虛擬機》

重載的方法在編譯過程中即可完成識別。具體到每一個方法調用,Java 編譯器會根據所傳入參數的聲明類型(注意與實際類型區分)來選取重載方法。選取的過程其實分為三個階段:

  1. 在不考慮對基本類型自動裝拆箱(auto-boxing,auto-unboxing),以及可變長參數的情況下選取重載方法;

  2. 如果在第 1 個階段中沒有找到適配的方法,那么在允許自動裝拆箱,但不允許可變長參數的情況下選取重載方法;

  3. 如果在第 2 個階段中沒有找到適配的方法,那么在允許自動裝拆箱以及可變長參數的情況下選取重載方法。

PS:如果 Java 編譯器在同一個階段中找到了多個適配的方法,那么它會在其中選擇一個最為貼切 的,而決定貼切程度的一個關鍵就是形式參數類型的繼承關系。

舉個例子:當傳入 null 時,它既可以匹配第一個方法中聲明為 Object 的形式參數,也可 以匹配第二個方法中聲明為 String 的形式參數。由於 String 是 Object 的子類,因此 Java 編譯 器會認為第二個方法更為貼切。

結合例子

根據以上理論,結合例子可以看到:

  • d.invoke(null);方法執行時滿足1階段的匹配規則,所以打印結果為 1;
  • d.invoke(null,1);方法執行時滿足1階段的匹配規則,故打印結果為 2;
  • d.invoke(null,2,1);方法執行時滿足階段2階段的匹配規則,所以打印 2
  • d.invoke(1,2,1);方法執行時滿足階段2階段的匹配規則,同時第一個參數無法匹配 String類型,故打印 1

無法精確匹配到方法時

Java 編譯器可能無法決定應該調用哪 個目標方法。

在這種情況下,編譯器會報錯,並且提示這個方法調用有二義性如圖所示:
image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM