2016-06-16 38 views
1

我很困惑面對這行代碼:瞭解Java是遞歸的類型抹除泛型類型定義

public abstract class ClassName<T extends ClassName<?>>{} 

我知道什麼是<T>,什麼是abstract,什麼是繼承,但我只是不能概括我所看到的就是這一行。

請有人可以用簡單的話來解釋這個有趣的事情是什麼意思? 不是關於<T><?>的問題的重複。令人困惑的是ClasName出現兩次。 在此先感謝。

回答

0

所以ClassName有一個通用的參數T這個參數需要滿足一定的要求,在這種情況下延長某種類型S,這意味着, T必須繼承S。現在在這種情況下有趣的是這個S

我們有SClassName<?>,所以T必須用通配符從ClassName繼承。對於通配符aka問號,請查看Michael Markidis在對您的問題發表評論時給出的鏈接。

真正的樂趣是現在,這個定義

public abstract class ClassName<T extends ClassName<?>> 

允許遞歸泛型類型確定指標。所以,你可以有類似

ClassName<ClassName<ClassName<ClassName<?>>>> test; 

不管什麼是值得:)

編輯:鑑於

ClassName2<T extends ClassName<?>> extends ClassName<T> 

多數民衆贊成在比較相對容易。我們希望繼承ClassName但不能「銷燬」泛型參數,所以我們接受一個ClassName會接受,在這種情況下爲T extends ClassName<?>。在extends ClassName<T>編譯器檢查這個(即ClassName2的)T是否符合ClassNameT,這是要求(記住ClassName的定義)T extends ClassName<?>,所以這顯然有效。

另外,我們有ClassName2<?>延伸ClassName<?>,所以現在你可以混合使用,但是你想將兩種類型:

ClassName2<ClassName<ClassName<ClassName<?>>>> test2; 
ClassName2<ClassName<ClassName2<ClassName<?>>>> test3; 

但是,如果你會,說

class ClassName3<T extends ClassName3<?>> extends ClassName<T> 

(公和abstrac修飾符並不真正影響這裏的通用行爲),你只能擁有像

ClassName3<ClassName3<ClassName3<ClassName3<?>>>> test4; 
ClassName2<ClassName<ClassName3<ClassName3<?>>>> test5; 

ClassNameClassName2不繼承ClassName3

+0

哦,我不敢聽到在這個上下文中的「遞歸」)))其實我下一個類有公共抽象類ClassName2 >擴展ClassName 。 –

+0

@Evgeniy Mishustin根據您的評論擴展了我的答案:-)我很高興Type Erasure提示可以幫助您 – GreenThor

1

public表示該類對所有其他類都可見。
abstract意味着該類不能實例化(您必須爲此找到一個非抽象的子類)
inheritance是面向對象編程中的一個重要概念。閱讀關於面向對象的書或諮詢維基百科。

T extends ClassName<?>表示在類型參數T上存在上限,因此T需要是ClassName<?>的子類。 ?表示無限類型參數。

我會提供一個更有意義的例子,可以使它更容易理解使用有界遞歸類型參數的概念。假設你有一個類Thingy。您希望Thingy的所有子類都具有可比性,但僅適用於相同的子類。也就是說你想釘相媲美的指甲,但沒有自行車:

interface Thingy<T extends Thingy<T>> extends Comparable<T> {} 

class Nail implements Thingy<Nail> { 
    @Override public int compareTo(Nail o) { ... } 
} 

class Bike implements Thingy<Bike> { 
    @Override public int compareTo(Bike o) { ... } 
} 
+0

令人困惑的是抽象類如何才能繼承它的類型類?這聽起來像是無休止的故事 –

+0

不是。你只需要看看子類的外觀如何...'類Foo擴展ClassName {}'和'class Bar extends ClassName {}'可以是兩個這樣的子類...... –

+0

@Evgeniy Mishustin通過Type Erasure ,泛型的重要概念。是的,這個永無止境的故事是很酷的,看到我的答案。甚至沒有知道這種可能性之前:-D – GreenThor