2010-12-15 11 views
11

私は私のAPIで、このようなものを提供したい:ジェネリッククラスの入れ子になったジェネリック

class Foobar extends AbstractThing<Double> 

class EventThing<Foobar> {  
      public Foobar getSource(); 
      public Double getValue(); 
} 

だから私はこの書き込み:

class EventThing<T extends AbstractThing<U>> {  
     public T getSource(); 
     public U getValue(); 
} 

をしかし、javaはUを解決することはできません。

代わりにEventThing<T extends AbstractThing<U>,U>で動作しますが、第2のUは実際には冗長であるため、AbtractThingはすでにタイプを定義しています。だから私はそれを取り除くことが大好きです。

答えて

26

あなたはそれを取り除くことはできません。 2番目のUは重複していません。コンパイラが最初のUを型パラメータとして解釈するようにしますが、コンパイラはそれを解釈しません。また、このことを書かれている可能性:このケースでDoubleは具象クラスではなく、型パラメータであることを

class EventThing<T extends AbstractThing<Double>> 

注意。以下に、この比較:これは上記のコードの最初の行とまったく同じ形状を有すること

class EventThing<T extends AbstractThing<U>> 

注意。コンパイラは、最初のケースではDoubleが具体的なクラスを意味し、後者の場合はUが型パラメータとして意味されることをどのように知っていますか?

コンパイラはそれを知ることができず、最初の行のDoubleのように、Uを具象クラスとして扱います。コンパイラはU typeパラメータであることを知らせるための唯一の方法は、そのように指定することです:

class EventThing<T extends AbstractThing<U>, U> 
+1

それはより多くのコンパイラの欠けている機能のように私には思えます。 編集: しかし、私はあなたのポイントを得る、あなたの答えに感謝します。 悪いです。私は穴の特徴を残しておくと思います。 –

+4

@Marcel:私はこの答えは、なぜコンパイラが 'U'が実際の型かジェネリック型のパラメータかを推測しようとすることができない理由を説明していると思います。 Javaでは、各ジェネリック型パラメータを正当な理由で明示的に宣言する必要があります。それがあなたに似ているかどうかにかかわらず、これは「コンパイラの欠けている機能」ではありません。 – ColinD

+1

@ColinD:私はMarcelには欠けているように見えますが、彼の例ではUは重複しているようです。明らかに、Uは型引数であることをコンパイラに知らせる必要がありますが、class EventThing >は基本的にUが可変型パラメータであることを示しています。議論の目的のためだけに、私はそれが醜いことに同意する)。この方法では、呼び出しコードに繰り返しはありません。 – Gilead

関連する問題