我有兩個編譯得很好的構造函數,但我希望Java抱怨模糊性的可能性。變量參數構造函數_可能會發生衝突,但編譯
public Foo(int id, Bar bar, String name, String description){
}
public Foo(int id, Bar bar, String... values){
}
什麼給了?
我有兩個編譯得很好的構造函數,但我希望Java抱怨模糊性的可能性。變量參數構造函數_可能會發生衝突,但編譯
public Foo(int id, Bar bar, String name, String description){
}
public Foo(int id, Bar bar, String... values){
}
什麼給了?
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將回暖,如果它的固定元數法能夠。
非常明確的解釋,謝謝。 – ajb
我同意你的肖恩,下面的代碼可以調用任何你定義的兩個構造函數:
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());
我希望幫助解釋,爲什麼你不不要讓編譯器抱怨它(這只是他們認爲它應該工作的方式)。
+1好問題。起初,我誤解了你的問題。 –