簡體   English   中英

Java遞歸通用模板:這是什么意思……S擴展了Writer <E> &gt;擴展實體 <E,S>

[英]Java Recursive generic template: what does this mean by … S extends Writer<E>> extends Entity<E,S>

有人可以解釋以下相當復雜的遞歸通用模板用法嗎?

public abstract class Data<E extends Data<E, S>,
                           S extends Writer<E>> extends Entity<E,S>

如上所述,在使用遞歸泛型時我們應該記住什么。 這些類型(這里是ES)之間的關系和規則如何?

如果有的話,請提供一些有關這種通用用法的資源/鏈接/書籍。 我知道一本關於這方面的書,《有效的Java》,約書亞·布洛赫(Joshua Bloch)第二版(第27項)

讓我們從最簡單的開始

S extends Writer<E>

任何類型為S的類都必須是類E的編寫者

extends Entity<E,S>

只是繼承,Data類擴展了Entity類。

E extends Data<E, S>

用於E的任何類都必須本身從Data類繼承,並使用其自身的類型和與其自身兼容的writer繼承/實現Data的通用方法。

E&S之間的關系應如下所示:

//E = Example, S = ExampleWriter
public class ExampleWriter implements Writer<Example>{
//...
}
public class Example extends Data<Example,ExampleWriter>{
//...
}

請記住:使用泛型提供Writer<SomeChildOfExample>Writer<SomeParentOfExample>可能會或可能不會產生編譯器錯誤,這取決於這兩種泛型類型中定義的泛型方法。

Data具有兩個參數, E必須最終成為其自身的實例,而S必須具有Writer自身的實例的能力(更具體地說,是E指定的自身的同類實例)。 最后, Data<E,S>還具有相同的ES參數化的Entity (即, Entity屬於Data<E,S>Writer<E> )的資格/繼承能力。

具體的實現可能看起來像

NumericalData extends Data<NumericalData, NumWriter>其中NumWriter工具/延伸Writer<NumericalData>NumericalData也有資格作為一個Entity<NumericalData, NumWriter>

編輯:

為什么要這樣? 可能需要在抽象類中定義通用方法,該方法依賴於滿足條件Data<E,S>的參數/返回值,但也希望能夠使用更顯式的類型返回/工作。 例如,在Data<E,S> ,可能存在

E doSomething(E toThis) { toThis.aDataClassMethod(); return toThis; }

該類可以進行第一個調用,因為它知道EData<E,S> ,並返回更具體的類型,因為它知道toThisE

坦白地說,遞歸泛型通常是通往太聰明的道路。 它們可能很有用,但是很多時候它們只是“精巧”的,人們試圖將問題轉向聰明的事物,而不是相反。

我同意Carl的觀點,遞歸類型傾向於“聰明”,但會犧牲可用性。 但是,在很多情況下,Java rtl應該采用這種慣用法來強制嚴格的類型安全性並避免我們作為類庫擁有的一堆猴子。

例如,即使Object至少也應該是抽象遞歸類型,以強制執行嚴格的相等性規則:

public abstract class Object<T extends Object<T>> {
  ...
  public boolean equals( o :T ) {
     ...
  }
}

equals()實現中沒有更多的instanceof檢查,更重要的是,equals()調用的編譯時檢查更好。

也就是說,也許更合適,更簡單的功能應該是“ Self”類型。

暫無
暫無

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

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