2011-03-25 43 views
1

的我有簡單通用類,如下所示:實例化的子類通用類型類

public class Test<T extends Number> { 

    public void doSomething() { 
     Test t = new Test(); 
     t.getNumber(); 

    } 

    public T getNumber() { 
     T d = new Double("1.5"); // I get an compiler error here! 
     return d; 
    } 
} 

的getNumber方法返回T(其延伸號),並在其它實施實例化一個雙。編譯器扔了一個錯誤就行了:

T d = new Double("1.5"); // I get an compiler error here! 

的錯誤是:

Incompatible types: 
[ERROR] found : java.lang.Double 
[ERROR] required: T 

因爲T擴展號碼,我本來期望這個工作。我錯過了什麼嗎?

回答

3

T擴展Number,但這並不意味着它擴展了Double。 Double只是Number的已知子類之一。

+0

我明白你的意思。雖然,這有點令人困惑。謝謝! – 2011-03-25 10:38:27

1

左側使用通用參數,右側使用通用參數並不正確。

0
T d = (T)new Double("1.5"); 

你必須類型轉換爲T.即使它解決您的問題,我覺得可疑的你在做什麼。

1
  1. 實例化測試時,您應該會收到編譯器警告。
  2. 想象一下,你實例化了Test<Integer>。然後getNumber方法中的行變爲:

    Integer d = new Double(「1.5」);

顯然,它應該拋出一個編譯器錯誤。

我認爲你不應該使用一個泛型類型參數 - 替換爲你的類:

public class Test { 
    public Number getNumber() { 
     Number d = Double.valueOf("1.5"); // No compiler error 
     return d; 
    } 
} 

另一種解決方案將被表達,你可以使用雙任何超作爲一種說法,即條件:

public class Test<T super Double> { 
    public T getNumber() { 
     T d = Double.valueOf("1.5"); // No compiler error 
     return d; 
    } 
} 

幾個一般提示:

  • 不要沒有良好的長方體基本類型原因。
  • 請勿使用new實例化盒裝的基元類型,而是在裝箱類中使用靜態工廠方法。
  • 請勿在沒有充分理由的情況下使用泛型類型。當你去定義一個泛型類型的麻煩時,不要在沒有類型參數的情況下實例化它。
0

通用類型定義class Test<T extends Number>意味着誰選擇創建類的對象可以選擇使用哪種類型的參數。用戶選擇,而不是您作爲類實現者。

這意味着你不能確定哪種類型將是,這樣你getNumber()方法只能安全地

  • 回報莫名其妙地進來作爲T對象
  • 回報null
  • 對象
  • 還有一些其他方法返回的對象T還給了。
    • 回報從Class<T>(或Class<? extends T>
    • 回報創建從Collection<T>(或Collection<? extends T>)的物體的目標
    • 類似