假設我們有這 3 個類:
class A { }
class B extends A { }
public class App {
static void f(int i, A a) { }
static void f(float j, B b) { }
static public void main() {
int i = 0;
B b = new B();
App.f(i, b);
}
}
這會產生錯誤:
App.java:11: error: reference to f is ambiguous
App.f(i, b);
^
both method f(int,A) in App and method f(float,B) in App match
1 error
為什么它不選擇型別f(int, A),因為i它是整數?
uj5u.com熱心網友回復:
之所以模棱兩可,原因有二:
- 兩種多載都適用,并且;
- 兩個多載都不比另一個更具體
請注意,可以使用引數呼叫f(int, A)多載和多載,因為存在從 to 的隱式轉換和從to的隱式轉換。f(float, B)(i, b)intfloatBA
當有不止一種適用的方法時會發生什么?Java應該選擇最具體的方法。這在語言規范的§15.12.2.5中有描述。事實證明,這些多載中的一個并非比另一個更具體。
一個適用的方法 m1 比另一個適用的方法 m2 更具體,用于使用引數運算式 e1、...、ek 的呼叫,如果以下任何一項為真:
m2 是通用的 [...]
m2 不是泛型的,m1 和 m2 可以通過嚴格或松散呼叫來應用,其中 m1 有形參型別 S1,...,Sn,m2 有形參型別 T1,...,Tn,型別 Si 更多對于所有 i (1 ≤ i ≤ n, n = k),引數 ei 比 Ti 更具體。
m2 不是通用的,并且 m1 和 m2 可通過變數 arity 呼叫應用 [...]
只有第二點適用于 的兩個多載f。為了使其中一個多載比另一個更具體,一個多載的每個引數型別都必須比另一個多載中的相應引數型別更具體。
對于任何運算式,如果 S <: T ( §4.10 ) ,型別 S 比型別 T 更具體。
注意“<:”是子型別關系。B顯然是 的一個子型別A。float實際上是 . 的超型別(不是子型別!)int。這可以從§4.10.1中列出的直接子型別關系推匯出來。因此,沒有一個多載比另一個更具體。
語言規范繼續談論最大限度地具體的方法,這并不真正適用于f這里。最后,它說:
否則,方法呼叫不明確,出現編譯時錯誤。
更多示例
static void f(int x) {}
static void f(float x) {}
當用 an 呼叫時int并不模棱兩可,因為int多載更具體。
static void f(int x, B a) {}
static void f(float x, A a) {}
當使用引數型別呼叫時(int, A)并不模棱兩可,因為(int, B)多載更具體。
static void f(int x, A a) {}
static void f(float x, A a) {}
當使用引數型別呼叫時(int, A)并不模棱兩可,因為(int, A)多載更具體。請注意,子型別關系是自反的(即A是 的子型別A)。
uj5u.com熱心網友回復:
請注意,在 java 中呼叫多載方法:
原始型別的優先順序:
相同型別 > 自動加寬 > 裝箱 > 向上轉換(父類) > 超類
參考型別的優先順序:
相同型別>向上轉換(父類)>超類>拆箱
解釋 :
// you have here a method who accept an int = same Type
// f(int i, A a) { } and this method can accept the other parameter
// because B is a subclass of A
int i = 0;
// But You have a method who accept a B reference = same Type
// f(float j, B b) { } and this method can accept the other parameter
// because float is actually a supertype of int as mentionned by Sweeper
B b = new B();
// So calling the method with an int and a B reference
// will confuse the compiler because both of the two methods
// can accept the other parameter
App.f(i, b);
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/410311.html
標籤:
