簡體   English   中英

實例化泛型類型類的子類

[英]Instantiating a sub class of generic type class

我有一個簡單的通用類,如下所示:

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(它擴展了Number),並在其實現中實例化一個Double。 編譯器在網上拋出一個錯誤:

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

錯誤是:

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

由於T擴展了Number,所以我期望它會起作用。 我想念什么嗎?

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

在左側使用通用參數,在右側使用特定的實現是不正確的。

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

    整數d = new Double(“ 1.5”);

顯然,它應該引發編譯器錯誤。

我認為您不應該使用泛型類型參數-將類替換為:

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

另一種解決方案是表達您可以使用Double的任何超類作為類型參數的條件,即:

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

一些一般性提示:

  • 沒有正當理由,不要裝箱原始類型。
  • 不要使用new實例化裝箱的基本類型,而應在裝箱類中使用靜態工廠方法。
  • 沒有正當理由,請勿使用泛型類型。 而且當您遇到定義泛型類型的麻煩時,請不要在沒有類型參數的情況下實例化它。
T d = (T)new Double("1.5");

您必須將強制類型轉換為T。即使它解決了您的問題,我也對您的工作感到懷疑。

通用類型定義class Test<T extends Number>意味着選擇創建Test類對象的任何人都可以選擇要使用的類型參數。 用戶選擇而不是您作為類實現者。

這意味着您無法確定它將是哪種類型,因此您的getNumber()方法只能安全地進行操作

  • 返回以某種方式作為T對象進入的對象
  • 返回null
  • 返回一個返回T其他方法返回的對象。
    • 返回從Class<T>創建的對象(或Class<? extends T>
    • Collection<T>返回一個對象(或Collection<? extends T>
    • 相似的東西

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM