跳過編譯器,獲取泛型參數的實際類型
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Vector;
public class GenericTest {
public static void main(String[] args) throws Exception {
//泛型類型是給編譯器看的,編譯成class字節碼文件後會丟棄類型信息,所以通過反射是無法知道泛型所存儲的實際類型的
List<String> list = new ArrayList<String>();
list.add("java");
//collection.add(20); //編譯報錯,因為編譯期間嚴格檢查泛型的實際數據類型
//由上結論可知,既然編譯成class文件後不會保存類型信息,那麼是不是就可以通過反射的方式存儲任意類型的數據呢?
//示例:通過反射在collection中存儲除String以外的數據
list.getClass().getMethod("add", Object.class).invoke(list,5);
list.getClass().getMethod("add", Object.class).invoke(list, new Date());
System.out.println(list.size()); //結果是3
//用下麵的方式去獲取元素會報ClassCaseException,因為List中第1和第2條記錄都不是String類型,所以取出來的時候會報類型轉換異常
//System.out.println(list.get(1));
//說明:上麵示例隻想說明,JAVA中的泛型是提供給編譯器檢查使用的,可以限定集合中的輸入類型,讓編譯器擋住源程序中的非法輸入,編譯器編譯帶類型說明的集合時會丟棄“類型”信息,使用程序運行效率不受影響
//由於無法在運行期間獲取某個帶類型的集合屬性的實際類型,但可以獲得方法參數列表中泛型參數的實際類型
Method method = GenericTest.class.getMethod("getGenericActualType", List.class,Vector.class);
Type[] types = method.getGenericParameterTypes();
for(int i = 0; i < types.length; i++) {
ParameterizedType pt = (ParameterizedType) types[i];
System.out.print("泛型原始類型: " + pt.getRawType() + "\t");
System.out.println("泛型實際類型: " + pt.getActualTypeArguments()[0]);
}
}
/*
* 獲得泛型參數的原始類型,示例方法
*/
public static void getGenericActualType(List<Date> list,Vector<String> vector) {
}
}
通過反編譯工具獲取GenericTest.class的源代碼:

最後更新:2017-04-02 22:16:21