Java 泛型在編譯期經過型別擦除,執行期無法直接獲取泛型參數。但透過反射 API 中的 ParameterizedType 與 Type 介面,我們仍能在特定情境下(方法參數、回傳值、欄位宣告)完整保留並獲取泛型資訊。本文透過實戰程式碼詳細示範。
Type:所有型別的公共介面ParameterizedType:參數化型別(如 List<String>)Method.getGenericParameterTypes():獲取方法泛型參數型別Method.getGenericReturnType():獲取方法泛型回傳型別package com.coscon.reflectionTest;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
public class ReflectionForGenerics {
// 測試方法:帶泛型參數
public void test01(Map<String, User> map, List<User> users) {
System.out.println("test01");
}
// 測試方法:帶泛型回傳值
public Map<Integer, User> test02() {
System.out.println("test02");
return null;
}
public static void main(String[] args) {
try {
Class<?> clazz = Class.forName("com.coscon.reflectionTest.ReflectionForGenerics");
// 1. 獲取方法參數泛型資訊
Method method = clazz.getMethod("test01", Map.class, List.class);
Type[] types = method.getGenericParameterTypes();
for (Type type : types) {
System.out.println("#" + type);
if (type instanceof ParameterizedType) {
Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
for (Type typeArg : actualTypeArguments) {
System.out.println("泛型參數型別:" + typeArg);
}
}
}
System.out.println("--------------------------------------------------------------");
// 2. 獲取方法回傳值泛型資訊
Method method2 = clazz.getMethod("test02");
Type returnType = method2.getGenericReturnType();
System.out.println("#" + returnType);
if (returnType instanceof ParameterizedType) {
Type[] typeArguments = ((ParameterizedType) returnType).getActualTypeArguments();
for (Type typeArg : typeArguments) {
System.out.println("回傳值泛型型別:" + typeArg);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
#java.util.Map<java.lang.String, com.coscon.reflectionTest.User>
泛型參數型別:class java.lang.String
泛型參數型別:class com.coscon.reflectionTest.User
#java.util.List<com.coscon.reflectionTest.User>
泛型參數型別:class com.coscon.reflectionTest.User
--------------------------------------------------------------
#java.util.Map<java.lang.Integer, com.coscon.reflectionTest.User>
回傳值泛型型別:class java.lang.Integer
回傳值泛型型別:class com.coscon.reflectionTest.User
instanceof 判斷後強制轉型,再呼叫 getActualTypeArguments()Map<String, List<User>> 需遞迴解析每一層 Type掌握反射獲取泛型資訊的技巧,是開發高階框架與工具的關鍵能力。雖然 Java 型別擦除機制限制了執行期泛型的完整可用性,但透過 ParameterizedType 仍能在關鍵位置獲得完整型別資訊,為泛型程式設計提供強大支援。