2013-01-01 36 views
1
class A { 

    public void printFirst(int... va) throws IOException{ 
     System.out.print("A"); 
    } 

    public static void main(String args[]) { 
     try { 
      new B().printFirst(2); 
     } catch (Exception ex) { 
     } 
    } 
} 


class B extends A { 

    //@Override 
    public void printFirst(float... va) throws IOException{ 
     System.out.print("B"); 

    } 
} 

曖昧爲什麼,它顯示參考調用曖昧 ??參考調用java中

回答

2

它實際上編譯,如果你刪除可變參數符號。字面2應該被認爲是int,而不是float,所以我期望編譯器會選擇A中的printFirst。

看起來這與編譯器如何執行方法調用轉換有關。 This SO question表示它在規範中,但與這個問題相關的接受答案的部分似乎是矛盾的(它說你不能將一個擴大的轉換(int到float)與可變參數結合起來,但後來它說這沒關係) 。我們討論了一個類似的問題in this question並且接受的答案認爲這種情況實際上是未指定的(不幸的是,討論的鏈接現在被破壞)。更糟的是,語言指南只是建議avoiding this type of overloading

+1

我不知道爲什麼你討論什麼其他的SO問題和答案不得不說的規範,而不是隻直接諮詢規格。但奇怪的是,從規範中可以很清楚地看出,這不應該是一個錯誤:'int ...'的版本嚴格比'float ...'的版本更具體(因爲int <:float '而不是'float <:int'),所以應該首選'int ...'的版本。 (請參閱http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.5。)所以這看起來像一個編譯器錯誤。 – ruakh

0

這似乎是您的編譯器中的一個錯誤;我可以在一個編譯器(Eclipse)中重現您的編譯錯誤,但不能在另一個編譯器(javac)中重現,我相信後者是正確的。

根據§15.12.2.5 "Choosing the Most Specific Method" of The Java Language Specification, Java SE 7 Edition,您看到的編譯錯誤應該只在「沒有方法是最具體的,因爲有兩個或多個最具體的方法」(加上其他各種限制)時纔會發生。但是,這不是這裏的情況:你的情況,B.printFirst(float...)最大限度具體,因爲一個方法是最大限度具體「,如果它是方便和適用,沒有其他是適用的,可訪問的方法是嚴格更具體「,在你的情況下,A.printFirst(int...)是嚴格更具體的,因爲intfloat的子類型和float不是int的子類型。

順便說一下,您的class B很可能是一個紅鯡魚;在Eclipse中,至少,你可以通過簡單地寫觸發相同的編譯錯誤:

class A 
{ 
    public static void printFirst(float... va) 
     { System.out.print("float..."); } 
    public static void printFirst(int... va) 
     { System.out.print("int..."); } 
    public static void main(String args[]) 
     { printFirst(2); } 
}