在 Java 的泛型系統中,ParameterizedType
和 TypeVariable
是兩個不同的類型表示,它們都屬于 java.lang.reflect.Type
接口的子接口。兩者都在反射(Reflection)中用于描述泛型信息,但用途和含義不同。
🌟 一、概念區別
類型名稱 | 所屬包 | 含義 |
---|---|---|
ParameterizedType | java.lang.reflect | 表示一個參數化類型,即帶有泛型參數的類型,例如 List<String> 、Map<Integer, String> 等。 |
TypeVariable | java.lang.reflect | 表示類型變量,也就是泛型中的占位符,如 T 、K 、V 等。 |
🧩 二、具體解釋
1. ParameterizedType
-
定義:
表示一個已經被參數化的泛型類型。 -
常見例子:
List<String>
Map<Integer, User>
Optional<T>
-
方法:
Type[] getActualTypeArguments(); // 獲取實際類型參數,如 String、Integer Type getRawType(); // 獲取原始類型,如 List、Map Type getOwnerType(); // 如果是內部類,返回外部類類型
-
使用場景:
在反射中獲取字段或方法的返回值類型時,如果它是參數化類型,就會返回ParameterizedType
。
示例:
Field field = MyClass.class.getDeclaredField("list");
Type type = field.getGenericType();if (type instanceof ParameterizedType pType) {Type rawType = pType.getRawType(); // java.util.ListType[] typeArgs = pType.getActualTypeArguments(); // [class java.lang.String]
}
2. TypeVariable
-
定義:
表示泛型中的類型變量(通常用 T、E、K、V 表示),這些變量會在編譯后被擦除,但在反射中可以獲取其信息。 -
常見例子:
- 泛型類定義中的
<T>
- 方法簽名中的
<K, V> Map<K,V> getMap()
- 泛型類定義中的
-
方法:
String getName(); // 獲取變量名,如 "T" Type[] getBounds(); // 獲取上界,默認是 Object GenericDeclaration getGenericDeclaration(); // 返回聲明該變量的類或方法
-
使用場景:
當你查看泛型類或方法的類型參數時,會得到TypeVariable
。
示例:
public class Box<T> {private T value;
}Field field = Box.class.getDeclaredField("value");
Type type = field.getGenericType();if (type instanceof TypeVariable<?> tv) {System.out.println(tv.getName()); // TSystem.out.println(Arrays.toString(tv.getBounds())); // [class java.lang.Object]
}
🔍 三、總結對比表
特性 | ParameterizedType | TypeVariable |
---|---|---|
表示類型 | 已經被參數化的類型 | 泛型類型變量(未指定具體類型) |
常見形式 | List<String> 、Map<K, V> | T 、E 、K |
是否有實際類型參數 | ? 有 (getActualTypeArguments ) | ? 沒有 |
是否代表泛型變量 | ? | ? |
使用場景 | 獲取具體泛型類型信息 | 獲取泛型變量本身信息 |
是否能直接用于創建對象 | ?(運行時被擦除) | ?(只是一個變量) |
💡 四、關系說明
在泛型類型中,TypeVariable
是泛型參數的“名字”,而 ParameterizedType
是這個“名字”被替換為具體類型的實例。
比如:
class Box<T> {T content;
}
content
字段的泛型類型是T
,是一個TypeVariable
- 如果你在某個地方這樣使用:
那么這里的Box<String> box = new Box<>();
Box<String>
就是一個ParameterizedType
,其中String
是對T
的具體化
? 五、補充:其他相關類型
除了這兩個類型外,Java 反射中還有幾個重要的類型接口:
類型 | 說明 |
---|---|
Class<T> | 表示具體的類或基本類型 |
WildcardType | 表示通配符類型,如 ? extends Number 、? super String |
GenericArrayType | 表示泛型數組,如 T[] |
在處理 JSON 反序列化(如 Gson、Jackson)、動態代理、框架設計等需要保留泛型信息的場景,理解這些類型是非常關鍵的。