2016-11-25 11 views
0

私の目標は、クラスインスタンスを受け入れる操作を実装することですが、コンクリートが渡されたクラスがCollectionから継承する場合のみです。Genericsを使用してクラス<?>のパラメータを正しく指定する方法

解決できないコードでコンパイラの警告が表示されます。

package com.fun.with.generics; 

import java.util.ArrayList; 
import java.util.Collection; 

public class AcceptTypedClass 
{ 
    // Warning here on 'Collection': ... raw type, references should be parameterized. 
    private static void printCollectionClass(Class<? extends Collection> c) 
    { 
     System.out.println(c.getName()); 
    } 

    public static void main(String[] args) 
    { 
     // Warning here on ArrayList: ... raw type, references should be parameterized. 
     Class<ArrayList> arrayList = ArrayList.class; 
     printCollectionClass(arrayList); 
    } 
} 

私は警告メッセージを理解していますが、次のような欠落型引数を追加して警告を修正すると、エラーが発生します。

Class<ArrayList<?>> arrayList = ArrayList.class; 

誰かがこれを説明できますか?問題は、私は上記のコードを書くことができますので、私は警告(とコードの作品)を得ることですか?

+1

「Class <」を試しましたか?コレクション> '? 'Class'が期待される場所では' ArrayList'を渡していることに注意してください。 –

答えて

0

あなたは、コレクションから継承したクラスを受け入れます

ここ printCollectionClass
private static <T extends Collection<?>> void printCollectionClass(Class<T> c) { 
     System.out.println(c.getName()); 
    } 
public static void main(String[] args) { 
     printCollectionClass(ArrayList.class); 
    } 

からprintCollectionClass方法を変更することができます。

+0

これが解決策です。 (しかし、私は認めます:コンパイラが今、なぜ幸せなのかという簡単な説明が私を助けます。) –

0

クラスは、実行時に利用可能なジェネリック型情報が存在しないため、一般的な「型トークン」、つまり実行時に特定の型を示す手段として根本的に悪い選択です。

それが使用することをお勧めします次のいずれか

  • クラスのインスタンス(適切なタイプの例えば空リスト) - これは単に任意の実行時の型情報を提供せず、型の安全性のコンパイラを満足ありません。
  • GSON's TypeTokenまたはGuice's TypeLiteralのような実際の "タイプトークン"クラス。

    はT. Javaはまだジェネリック型を表現する方法を提供していないジェネリック型を表しますので、このクラスが行います。この2つのクラスのJavadocで始まること

    お知らせ...

    A GSONタイプのトークンがTypeTokenの匿名のサブクラスを作ることによって作成されます。

    TypeToken<ArrayList<String>> typeToken = new TypeToken<ArrayList<String>>() {}; 
    

    サブクラスの行為はtypeToken.getClass().getGenericSuperclass()を経由して、typeTokenインスタンスにジェネリック型情報を焼きます。

    一般的なことはできませんが、実際のクラスをタイプパラメータではなくジェネリックパラメータとしてサブクラスを作成する必要があります。

関連する問題