2016-06-16 32 views
1

の理解Javaの再帰的なジェネリック型定義、私はこのコード行が直面している非常に混乱しています:型消去

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

私が継承が何である、abstractあるもの、<T>が何であるかを知っているが、私はちょうどまとめることはできません私はこの行にすべて見ています。

誰かが簡単な言葉で説明すると、その面白いことはどういう意味ですか? <T><?>についての重複はありません。ここで混乱するのは、ClasNameが2回出現することです。 ありがとうございます。

答えて

0

だからClassNameは、一般的なパラメータTを持っており、このパラメータは、特定の要件に合わせて必要があり、この場合には意味ある特定のタイプSを拡張しますTは、Sを継承する必要があります。この場合の興味深いのは、Sです。

SClassName<?>であるため、Tは、ClassNameからワイルドカードを継承する必要があります。ワイルドカードの場合、疑問符はMichael Markidisがあなたの質問にコメントしたリンクを見てください。

本当の楽しみは今、この定義

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

再帰ジェネリック型定義のそれぞれで独立しできることです。だから、それは価値があるものは何でものために

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

のようなものを持つことができます:)

EDIT:比較して比較的容易

ClassName2<T extends ClassName<?>> extends ClassName<T> 
を考えるのthatsを。 ClassNameを継承したいが汎用引数を "破棄"しないので、 ClassNameが受け入れるものを受け取ります。この場合は T extends ClassName<?>です。 extends ClassName<T>では、コンパイラは、の) Tが(これは明らかに ClassNameの定義を覚えています)の Tに適合するかどうかをチェックします。また

、我々はあなたが欲しいしかし、今あなたは二つのタイプを混在させることができ、ClassName<?>ClassName2<?>拡張している:

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

はしかし、あなたが持っているならば、パブリック(

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

言いますアブストラクモディファイアはここでの一般的な動作に実際には影響しません)、

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

ClassNameClassName2は、ClassName3を継承していません。

+0

ああ、私はこの文脈で "再帰的"を聞くのが怖かった)))実際に次のクラス私はpublic abstract class ClassName2 > ClassName を継承しています。 –

+0

@Evgeniy Mishustinはあなたのコメントに応じて私の答えを拡張しました:-)私はType Erasureのヒントがあなたを助けることができてうれしいです – GreenThor

1

publicは、クラスが他のすべてのクラスで可視であることを意味します。
abstractは、クラスをインスタンス化できないことを意味します(そのために非抽象サブクラスを見つける必要があります)
inheritanceはオブジェクト指向プログラミングの重要な概念です。 OOPに関する書籍を読むか、ウィキペディアに相談してください。

T extends ClassName<?>TClassName<?>のサブクラスである必要がありますように、タイプパラメータTの上限プットがあることを意味します。 ?は、無制限型パラメータを意味します。

ここでは、有界再帰型パラメータの使用の概念を理解しやすくするために、もう少し意味のある例を提供します。クラス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を拡張します {} 'クラスバーはClassNameを拡張します {}'はそのようなサブクラスの2つになります... –

+0

@Evgeniy Mishustin That Erasure 、ジェネリックの重要な概念。そして、はい、それについての素朴な話は、私の答えを見てください。その可能性を知りませんでした:-D – GreenThor