2012-05-10 38 views
1

好吧,我只想確認一些東西。重載繼承類型的參數

我正在爲java的Properties類創建一個包裝類,並且我提出了一個小問題。

,如果我有

public static void set(String key, Object value) { _p.set(key, value.toString()); } 

public static void set(String key, SomeClass value) { _p.set(key, value.SomeMethod().toString()); } 

Object超載稱爲只有當沒有其他重載足夠?

+2

'boolean'不從'Object'導出,因爲它是一個[原始](HTTP ://docs.oracle。com/javase/tutorial/java/nutsandbolts/datatypes.html) – amit

+0

我知道原語是什麼。可以像布爾一樣容易。 – Qix

回答

3

Java將選擇最具體的匹配項,在你的情況下,一個布爾值將被自動轉換爲自動裝箱布爾型< - > Boolean。如果你使用任何其他類型的字符串,將使用對象變體。

的詳細信息您在Java Language Specification 見8.4.9響應超載

新增找到評論:

class A { 
    public void print(Object o) { 
     System.out.println("A.print " + o); 
    } 

    public static void main(String[] args) { 
     B b = new B(); 
     A a = new A(); 
     b.print("test b"); 
     a.print("test a"); 
     ((A) b).print("test a or b"); 
    } 
} 

class B extends A { 
    public void print(Object o) { 
     System.out.println("B.print " + o); 
    } 
} 

打印:

您可以輕鬆地像一些代碼測試的行爲:

B.print test b 
A.print test a 
B.print test a or b 

我希望現在更清楚會發生什麼。

+1

Java將選擇*最具體*匹配。 – EJP

+0

好的,所以使用最新的適用衍生物。謝謝! – Qix

+0

@EJP謝謝我改變了 – stacker

4

這是一個非常危險的模式,實際上建議不要在Effective Java中顯式使用。問題在於方法簽名解析在編譯時會靜態地發生,所以它不依賴於運行時的實際參數類型,而只依賴於它們的聲明類型。

+0

我想的很多。在我問這個問題之前,我已經把它改成了特定的類型(沒有'Object'類型),但問題依然存在。 – Qix

2

它取決於您傳遞給此方法的參考文獻的類型。例如。

Objeyt myObject = Boolean.TRUE; 
YourClass.set("foo", myObject); 

援引其參數列表與布爾的方法。它會選擇Object版本。

參見例如在您的jdk中構造java.util.TreeSet(Collection c)的構造函數。類似的東西也在那裏進行(它檢查集合是否實際上是SortedSet,但SortedSet的構造函數)。

嘗試

public class A { 

    public void method(String str) { 
     System.out.println("foo"); 
    } 

    public void method(Object obj) { 
     System.out.println("bar"); 
    } 

    public static void main(String[] args) { 
     A a = new A(); 
     Object obj = "A String"; 
     a.method(obj); 
    } 

} 

這將打印酒吧。奇怪,但真正:)

+0

+1爲參考類型。 – Qix

0

過帳下面的例子:

public class Inherit { 
    public static void main(String[] args) { 
    System.out.println("Hello, Inheritance!"); 

    Parent parent = new Parent(); 
    Parent childp = new Child(); 
    Child childc = new Child(); 

    System.out.println("==============================="); 
    parent.print(parent); 
    parent.print(childp); 
    parent.print(childc); 

    System.out.println("==============================="); 
    childp.print(parent); 
    childp.print(childp); 
    childp.print(childc); 

    System.out.println("==============================="); 
    childc.print(parent); 
    childc.print(childp); 
    childc.print(childc); 

    } 

} 

class Parent { 
    public void print(Parent x) { 
     System.out.println("Parent.print(Parent)"); 
    } 
} 

class Child extends Parent { 

    public void print(Child x) { 
     System.out.println("Child.print(Child)"); 
    } 

    @Override 
    public void print(Parent x) { 
     System.out.println("Child.print(Parent)"); 
    } 
} 

和輸出

Hello, Inheritance! 
=============================== 
Parent.print(Parent) 
Parent.print(Parent) 
Parent.print(Parent) 
=============================== 
Child.print(Parent) 
Child.print(Parent) 
Child.print(Parent) 
=============================== 
Child.print(Parent) 
Child.print(Parent) 
Child.print(Child)