2013-10-14 43 views

回答

7

Java允許這些方法存在,因爲它具有關於如果兩者都適用時將調用哪一個的規則。具體而言,將通過變量arity方法(使用...)選擇固定方法(不包括...)。

第一階段(§15.12.2.2)執行過載分辨率而不 允許拳擊或取消裝箱轉換,或使用可變元數 的:

JLS, Section 15.12.2的,確定選擇哪種方法,當指出以下方法調用。如果在此階段沒有找到適用的方法 ,則處理繼續到第二階段。

這保證了該是有效的在Java SE 5.0之前的Java編程語言 任何電話不被認爲模棱兩可的結果引進的變量元數法,隱式裝箱和/或 拆箱的 。但是,變量數組方法(§8.4.1) 的聲明可以更改爲給定方法方法調用 表達式選擇的方法,因爲在第一階段中將變量數組方法視爲固定的方法。例如,在一個已經聲明m(Object)的類中聲明m(Object ...) 可以使m(Object)更長地被選擇用於某些調用表達式(例如m(null)),作爲 m對象[])更具體。

第二階段(§15.12.2.3)執行重載解析而 允許裝箱和拆箱,但仍排除使用可變 元數的方法調用的。如果在 階段沒有找到適用的方法,則處理繼續到第三階段。

這確保如果方法調用適用於通過固定方法調用 調用,方法調用將不會通過變量參數 選擇方法。

第三階段(§15.12.2.4)允許將超載與 可變陣列方法,裝箱和拆箱相結合。

(重點煤礦)

示例代碼:

class Bar{} 

public class Foo{ 
    public static void main (String [] args){ 
     Foo main = new Foo(1, new Bar(), "name", "description"); 
     Foo main2 = new Foo(2, new Bar(), "name"); 
     Foo main3 = new Foo(3, new Bar(), "name", "description", "otherValues"); 
     Foo main4 = new Foo(4, new Bar());  
    } 

    public Foo(int id, Bar bar, String name, String description) { 
     System.out.println("name and description!"); 
    } 

    public Foo(int id, Bar bar, String... values) { 
     System.out.println("values!"); 
    } 
} 

此打印出:

name and description! 
values! 
values! 
values! 

...表明Java將回暖,如果它的固定元數法能夠。

+1

非常明確的解釋,謝謝。 – ajb

0

我同意你的肖恩,下面的代碼可以調用任何你定義的兩個構造函數:

Foo foo = new Foo(3, new Bar(), "", ""); 

然而,當Java人們推出了「可變參數符號」,他們決定,上述將稱爲「最特殊的構造函數」。在這種情況下,我有2個字符串參數,你的第一個構造函數需要2個字符串參數,所以它會被調用。

第二個構造函數只被調用,如果有多於或少於2個字符串參數,例如:

Foo foo = new Foo(3, new Bar(), "", "", ""); 

甚至:

Foo foo = new Foo(3, new Bar()); 

我希望幫助解釋,爲什麼你不不要讓編譯器抱怨它(這只是他們認爲它應該工作的方式)。

相關問題