簡述
在同一個類中,如果多個方法有相同名字、不同參數,即稱爲重載。在編譯器眼中,方法名稱+參數類型+參數個數,組成一個唯一鍵,稱爲方法簽名,JVM通過這個唯一鍵決定調用哪種方法。(注意方法返回值並非這個組合中的一員)
優先級
有時候通過肉眼就可以辨別出JVM會調用哪個方法,但有時候卻容易混淆,如下代碼
public class Test {
public static void test(int i){
System.out.println("this is test(int i)");
}
public static void test(Integer i){
System.out.println("this is test(Integer i)");
}
public static void test(int... i){
System.out.println("this is test(int... i)");
}
public static void test(Object i){
System.out.println("this is test(Object i)");
}
}
如果調用test(1)會真正調用哪個方法呢?
下面給出相關的優先級
-
精確匹配
精確匹配是指對於前兩個方法,如果調用時傳入的是基本數據類型,會執行第一個方法,傳入的是包裝類型,會執行第二個方法 -
如果是基本數據類型,自動轉換成更大範圍的基本類型
是指如果將第一個方法的入參改爲(long i),此時調用test(1)仍然是執行本方法,它的優先級高於(Integer i) -
自動拆裝箱
這個很好理解,這裏不解釋了 -
通過子類向上轉型繼承路線依次匹配
如Integer的父類是Object。這裏需要注意null可以匹配任何對象,如test(null)會調用參數爲Integer的方法,如果添加一個參數爲String的方法就會編譯報錯了,因爲無法確定null應該選擇Integer還是String 通過可變參數匹配
-
注意
以下情況是無法調用test(1, 2)的,你是在挑戰編譯器忍耐極限!
public static void test(Integer i, int j){
System.out.println("1");
}
public static void test(int i, Integer j){
System.out.println("2");
}