簡體   English   中英

從Java的子類實例調用的類的泛型方法對返回實例的類的誤解

[英]Misunderstanding of class of returned instance from generic method of class called from subclass instance in Java

例:

interface S {}

interface SS extends S {}

abstract class A<T extends S> {
    T get() {…}
}

abstract class B<BT extends SS> extends A<BT> {}

當編譯器可以確定返回的對象至少為SS類型時,為什么((B)someInstanceOfB).get()返回S類型的對象(我們應該將其手動轉換為SS )?

為何編譯器不進行隱式類強制轉換以使代碼更清晰? 該代碼的版本為1.5+,這對於編譯器而言不是秘密。 (解決了)

更新:為什么編譯器不編譯B類,因為它隱式具有方法BT get() { return super.get(); } BT get() { return super.get(); }

Java 1.7+是否解決了這個問題?

通過強制轉換為B您正在使用原始類型

使用原始類型會從對象中刪除所有通用信息 ,無論它在哪里。

這意味着對於原始類型Bget方法看起來像在返回S (因為這是類型參數T的擦除(即,運行時使用的實際類型))。

為了避免這種情況, 切勿使用原始類型 它們專用於向后兼容以及與舊代碼的交互。

轉換為B<? extends SS> B<? extends SS>

不會:在Java的任何將來版本中,這個問題可能永遠不會“解決”,因為正確使用泛型時將不存在該問題。

關於更新:沒有, B 沒有一個方法BT get() 它具有方法T get() ,其中T綁定到具有下界SS的類型參數BT 但是由於使用原始類型時會丟棄所有通用類型信息,因此T 仍會退回到原始擦除S

規則很簡單,基本上說“當您使用原始類型時,它的作用就好像該類根本沒有泛型”。 但是,這種情況並不總是很明顯。

您沒有參數化B的實例。

假設您有C類實現SS

然后, new B<C>().get(); 將返回類型為C的對象。

new B().get(); 一行,您的IDE必須告訴您“ B是原始類型。對泛型B的引用應該參數化。”

暫無
暫無

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

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