Java之泛型ParameterizedType、getGenericSuperclass、getActualTypeArguments

在反射中,我們經常遇到這樣代碼: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>的擁有者;

 

資料源自互聯網,經綜合整理而成,若有侵犯,請聯繫作者。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章