2016-07-27 9 views
3

ジェネリックに関する質問があります。境界を持つジェネリックをコンパイルする際のエラー

私がクラス内にこのスニペットを持っている(のは、ケース1にそれを呼びましょう):

static { 
    final List<Class<? extends A>> typeList = Arrays.asList(
     C.class, 
     D.class 
    ); 
} 

public interface A {…} 

public class C extends B {…} 

public class D extends B {…} 

public abstract class B implements A {…} 

Androidのメーカーが文句を言うと、それは上記の行final List…にコンパイルされません。

互換性のないタイプ
必須リスト< クラス<?拡張A > >
Found List < クラス<?

static { 
    final List<Class<? extends A>> typeList = Arrays.asList(
     C.class, 
     D.class 
    ); 
} 

public interface A {…} 

public class C implements A {…} 

public class D implements A {…} 

と、それはコンパイル:B > >

しかし、以前、私はこのコードを(のは、ケース2、それを呼びましょう)だったが拡張

だから、私はこの中にケース1を変更するだけで問題を絞り込むために、試み:

static { 
    final List<Class<? extends A>> typeList = Arrays.asList(
     B.class 
    ); 
} 

Bがケース2にちょうどCとDのように、Aを実装していることに注意してください。しかし、コンパイラはまだ不平を言う。

私はこの問題を理解するためのアイデアがありません。私はJava Language Specificationタイプと値の章を読んでいますが、それでも何もありません。

私はStackOverflowで検索しましたが、同様の質問は見つかりませんでした。

任意のポインタ? (PS:誰かが行う前に、XKCDを必須としています)

+0

私のためにうまくコンパイルします。 Java 7を使用している場合は、明示的な型引数を使用することができます。 –

+0

Sotiros Delimanolis、確かにその質問と重複しています。 –

答えて

6

問題は型推論の問題です。 Java 8以前では、Arrays.asListのインスタンス化を決定する際に、typeListの型を使用するという推論ではコンパイラが十分にスマートではなかったので、それは単独で発生します。

は、この明示的なヒントをお試しください:

final List<Class<? extends A>> typeList = Arrays.<Class<? extends A>>asList(
    B.class 
); 

は、より詳細に移動するには、コンパイラがちょうど単独でこれ見ている:

Arrays.asList(
    C.class, 
    D.class 
); 

それが割り当てられているものを見ません。 Class<? extends A>ではなく、Class<? extends B>が選択されます。これは、すべての引数に共通する最も特殊なスーパータイプであるためです。

+0

Whoa。良いですね。 – Mena

+0

それは完璧に働いた!あなたは素早く、すぐにStackOverflowで私はそれを受け入れることができません! Mark Petersありがとうございました。 –

関連する問題