2012-02-16 32 views
4
import java.util.*; 

// Let's define a self-referential type: 
class SelfReferential<T extends SelfReferential<T>> {} 

//A complete (i.e. not parameterized) subtype of SelfReferential: 
class SubclassA extends SelfReferential<SubclassA> {} 

//A partial (i.e. parameterized) subtype of SelfReferential: 
class SubclassB<T extends SubclassB<T>> extends SelfReferential<T> {} 

//Two complete subtypes of SubclassB 
class SubclassB1 extends SubclassB<SubclassB1> {}  
class SubclassB2 extends SubclassB<SubclassB2> {} 

//Now let's define a generic type over SelfReferential: 
class Generic<T extends SelfReferential<T>> {} 

//No problem creating a subtype for A, B1 or B2 
class GenericA extends Generic<SubclassA> {} 
class GenericB1 extends Generic<SubclassB1> {}  
class GenericB2 extends Generic<SubclassB2> {} 

//We can also defined a parameterize type for specific types extending SubclassB 
class GenericB<T extends SubclassB<T>> extends Generic<T> {} 

//However, it does not seem possible to define a non-parameterized subtype of Generic of ANY subtype of SublassB 
//My goal is to provide a type alias for GenericB<? extends SubclassB<?>> to avoid 
//having to mention it everywhere in the code. This is like providing an alias for ArrayList<String> using 
class ArrayListOfString extends ArrayList<String> {} 

//Unsucessful attempts: 
//class GenericAnyB extends Generic<SubclassB> {} //ERROR: bound mismatch 
//class GenericAnyB extends Generic<SubclassB<?>> {} //ERROR: bound mismatch 
//class GenericAnyB extends Generic<? extends SubclassB<?>> {} //ERROR: invalid syntax: a supertype cannot specify any wildcard 
//class GenericAnyB extends Generic<SubclassB<? extends SubclassB>> {} //ERROR: bound mismatch 
//class GenericAnyB extends Generic<SubclassB<SubclassB<SubclassB<SubclassB<SubclassB<SubclassB>>>>>> {} // well... 
//class GenericAnyB extends <T extends SubclassB<T>> Generic<T> {} //ERROR: this syntax is illegal 

要点、extend節に「参照サイクル」を指定することはできません。ジェネリック型の自己参照型のJavaサブクラス化問題

質問:これはJava言語の制限ですか?

答えて

1

これは可能ではありません。自己参照型の変数を宣言するのは、ワイルドカードや生の種類がなければ不可能です。自己参照の型パラメータなしでバインドとして使用できないのと同じ理由で、SubclassBを直接インスタンス化することはできません。

この制限に関する詳細な議論については、この記事を参照してください:Self bound generic type with fluent interface and inheritance

一番下の行はGenericAnyBがバウンドとしてSubclassBを使用する一般的なそのものである必要があるということです。

だけ余分を追加
class GenericAnyB<T extends SubclassB<T>> extends Generic<T> { } 

どの段階でも使用できるようになる前に、階層にステップを進めてください。

class GenericB1 extends GenericAnyB<SubclassB1> { } 
class GenericB2 extends GenericAnyB<SubclassB2> { } 
関連する問題