在反射中,我們經常遇到這樣代碼:ParameterizedType、getGenericSuperclass、getActualTypeArguments,今天就讓我們來了解一下。
先來看一段代碼:
這段代碼啥意思?引用一段測試代碼:
public class Person<T> {
}
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public class Student extends Person<Student> {
public static void main(String[] args) {
Student st = new Student();
Class clazz = st.getClass();
// getSuperclass()獲得該類的父類
System.out.println(clazz.getSuperclass()); // 輸出:class com.test.Person
// getGenericSuperclass()獲得帶有泛型的父類
// Type是 Java 編程語言中所有類型的公共高級接口。它們包括原始類型、參數化類型、數組類型、類型變量和基本類型。
Type type = clazz.getGenericSuperclass();
System.out.println(type); // 輸出:com.test.Person<com.test.Student>
// ParameterizedType參數化類型,即泛型
ParameterizedType p = (ParameterizedType)type;
// 獲得父類的泛型參數的實際類型
// getActualTypeArguments返回的是一個數組,泛型參數的實際類型可能有多個
Class c = (Class) p.getActualTypeArguments()[0]; // 取數組第1個
System.out.println(c); // 輸出:class com.test.Student
}
}
Type是什麼?
Type是Java 編程語言中所有類型的公共高級接口(官方解釋),也就是Java中所有類型的“爹”;其中,“所有類型”的描述尤爲值得關注。它並不是我們平常工作中經常使用的 int、String、List、Map等數據類型,而是從Java語言角度來說,對基本類型、引用類型向上的抽象;
Type體系中類型的包括:原始類型(Class)、參數化類型(ParameterizedType)、數組類型(GenericArrayType)、類型變量(TypeVariable)、基本類型(Class);
原始類型,不僅僅包含我們平常所指的類,還包括枚舉、數組、註解等;
參數化類型,就是我們平常所用到的泛型List、Map;
數組類型,並不是我們工作中所使用的數組String[] 、byte[],而是帶有泛型的數組,即T[] ;
基本類型,也就是我們所說的java的基本類型,即int,float,double等
空接口
Type是個空接口,沒有定義任何方法,通過多態提高了程序的擴展性,具體實現去看下面的子類;
Type接口下共有4個"兒子",每一個“兒子”代表着Java中的一種類型;
1.ParameterizedType
參數化類型,即泛型;例如:List<T>、Map<K,V>等帶有參數化的對象;
以上,簡單介紹了Java-Type的體系;爲了解決泛型,JDK1.5版本開始引入Type接口;在此之前,Java中只有原始類型,所有的原始類型都是通過Class進行抽象;有了Type以後,Java的數據類型得到了擴展,從原始類型擴展爲參數化類型(ParameterizedType)、數組類型(GenericArrayType)、類型變量(TypeVariable);
1.ParameterizedType
在ParameterizedType接口中,有3個方法,分別是getActualTypeArguments()、 getRawType()、 getOwnerType();
如:Map<Integer, String>
Type[] getActualTypeArguments()
: 返回實際泛型類型列表, 如上面那個Map<Integer, String>的實際
泛型數組中有兩個元素,第1個是Integer,第2個是
String。
Type getRawType()
: 返回承載該泛型信息的對象, 如上面那個Map<Integer, String>
承載範型信息的對象是Map
Type getOwnerType()
: 返回是誰的member.(上面那兩個最常用)
1.1 getActualTypeArguments
獲取泛型中的實際類型,可能會存在多個泛型,例如Map<K,V>,所以會返回Type[]數組
值得注意的是,無論<>中有幾層嵌套(List<Map<String,Integer>),getActualTypeArguments()方法永遠都是脫去最外層的<>(也就是List<>),將尖括號內的內容(Map<String,Integer>)返回;
我們經常遇到的List<T>,通過getActualTypeArguments()方法,得到的返回值是TypeVariableImpl對象,也就是TypeVariable類型(後面介紹);
1.2 getRawType
獲取聲明泛型的類或者接口,也就是泛型中<>前面的那個值
1.3 getOwnerType
通過方法的名稱,我們大概瞭解到,此方法是獲取泛型的擁有者,那麼擁有者是個什麼意思?
Returns a {@code Type} object representing the type that this type
* is a member of. For example, if this type is {@code O.I}, return a representation of {@code O}. (摘自JDK註釋)
通過註解,我們得知,“擁有者”表示的含義--內部類的“父類”,通過getOwnerType()方法可以獲取到內部類的“擁有者”;例如: Map 就是 Map.Entry<String,String>的擁有者;
資料源自互聯網,經綜合整理而成,若有侵犯,請聯繫作者。