2013-09-27 96 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>。所以,這個結果很清楚。


至於你的第二種情況,你傳遞一個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),一個該類型的每個可能調用參數部分 通過類型參數。所有這些參數化類型在運行時共享相同的 類。

例如,執行的代碼:

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

將導致變量b保持值true

換句話說,getGenericSuperClass()方法不會給你,你在實例類使用的實際類型參數,但它是擴展類使用的類型參數。現在,因爲java.util.ArrayList的通用超類是AbstractList<E>。因此,您獲得的類型參數僅爲E