2013-09-27 12 views
5

これはなぜ起こっているのですか?私が匿名ジェネリッククラスを型判定メソッドに渡すと、すべてが良いことです。私はこの方法でオブジェクトを渡す場合でも - コンソール出力はE.実行時ジェネリック型の判定

public static void main(String[] args) { 

    printType(new ArrayList<Integer>() {}); 
    printType(new ArrayList<Integer>()); 

} 

public static void printType(final List<?> list) { 
    System.out.println(((ParameterizedType) list.getClass().getGenericSuperclass()).getActualTypeArguments()[0]); 
} 

コンソールは次のとおりです。

class java.lang.Integer 

E 

は私に説明してください。

+0

あなたは何をしようとしていますか? –

+0

あなたのリストの型パラメータを印刷しています –

+0

実行時に型のパラメータを取得しようとしています –

答えて

7

最初の呼び出しは、ArrayList<Integer>の匿名サブクラスのインスタンスを渡しています。だから、それはに似ています:

class YourClass extends ArrayList<Integer> 

、あなたのようにメソッドを呼び出す:

printType(new YourClass()); 

あなたのケースでYourClassの汎用的なスーパークラスまたは匿名クラスをArrayList<Integer>だけです。したがって、その出力は明らかです。


2番目のケースでは、ArrayList<Integer>というインスタンスを渡しています。このクラスの定義がどのように見えると:

だから、
public class ArrayList<E> extends AbstractList<E> 
     implements List<E>, RandomAccess, Cloneable, java.io.Serializable 

、ここでは一般的なスーパークラスはAbstractList<E>です。ジェネリック型を共有し、同じClassインスタンスの

インスタンス化:ArrayListのすべてのインスタンスが実行時に同じクラスを共有することが

注:

new ArrayList<Integer>().getClass() == new ArrayList<String>().getClass(); 

上記の比較はあなたにtrueを与えるだろう。 getClass()呼び出しの両方があなたに戻って与えるので:

class java.util.ArrayList 

JLS 8.1.2: Generic Classes and Type Parametersを参照してください:

ジェネリッククラス宣言は、パラメータ化された型 (§4.5)のセットを定義し、タイプの可能な各呼び出しのための1型引数別のパラメータセクション これらのパラメータ化された型はすべて、実行時に同じ クラスを共有します。例えば

、コードを実行する:

Vector<String> x = new Vector<String>(); 
    Vector<Integer> y = new Vector<Integer>(); 
    boolean b = x.getClass() == y.getClass(); 

trueを保持する変数bをもたらすであろう。言い換えれば

getGenericSuperClass()方法は、あなたのクラスをインスタンス化しながら、実際に使用する型引数が、それが拡張され、クラスで使用されるタイプのパラメータを与えることはありません。今、java.util.ArrayListの汎用スーパークラスはAbstractList<E>です。したがって、取得するタイプパラメータはEのみになります。

関連する問題