【Java基礎】Java中如何獲取一個類中泛型的實際類型


泛型的術語

<>: 念做typeof

List<E>: E稱為類型參數變量

ArrayList<Integer>: Integer稱為實際類型參數

ArrayList<Integer>: 整個ArrayList<Integer>稱為參數化類型(對應着java.lang.reflect.ParameterizedType接口)

泛型反射相關API

Type[] getGenericInterfaces():獲得當前類實現的泛型接口(參數化類型)

舉例1:

1)定義類A,C 接口B

//類B
public interface B{}


//類C
public class C{}


//A實現B,向B傳入實際類型參數C
public class A implements B<C>{}

2)測試代碼

A a = new A();
Type[] types = a.getClass().getGenericInterfaces();
for (Type type : types) {
          System.out.println(type);//結果是:B<C>
}

Type[] getGenericSuperclass():獲得帶有泛型的父類

舉例2:

1)定義3個類A,B,C

//類B
public class B{}


//類C
public class C{}


//A繼承B,向B傳入實際類型參數C
public class A extends B<C>{}

2)測試代碼

A a = new A();
Type type = a.getClass().getGenericSuperclass();
System.out.println(type);//結果是:B<C>

ParameterizedType:參數化類型接口,Type的子接口

通過上面兩個案例可知getGenericInterfaces和getGenericSuperclass可以獲取到參數化類型B ,並且ParameterizedType是Type的子接口,將Type強轉成ParameterizedType。ParameterizedType提供了一個getActualTypeArguments()方法,這個方法可以獲取參數化類型中的實際類型參數。

舉例3:我們對案例2測試代碼進行修改

A a = new A();
//獲得帶有泛型的父類
Type type = a.getClass().getGenericSuperclass();
System.out.println(type);//結果是:B<C>
//將type強轉成Parameterized
ParameterizedType pt = (ParameterizedType )type;
/*得到父類(參數化類型)中的泛型(實際類型參數)的實際類型。
getActualTypeArguments()返回一個Type數組,之所以返回Type數組,是因為一個類上有可能出現多個泛型,比如:Map<Integer,String>
*/
Type [] actualTypes = pt.getActualTypeArguments();
System.out.println(actualTypes[0]);//結果:C

獲取接口泛型的實際類型參數做法跟上面代碼差不多,只需要把

Type type = a.getClass().getGenericSuperclass(),改成 Type type = a.getClass().getGenericInterfaces()就可以了。

public BasicAction(){
  try {
    //獲取子類字節碼文件對象,this代表的是子類對象。
    Class clazz = this.getClass();
    //獲取子類所屬接口的參數化類型,cn.xxx.xxx.BasicAction<cn.xxx.xxx.Standard>
    Type type = clazz.getGenericSuperclass();
    //因為type是頂級接口沒有定義任何方法,所以需要強轉為子接口ParameterizedType
    ParameterizedType parameterizedType = (ParameterizedType) type;
    //通過子接口定義的getActualTypeArguments方法獲取到實際參數類型,<cn.xxx.xxx.Standard>
    //返回參數為數組,因為Java中接口可以多實現
    Type[] types = parameterizedType.getActualTypeArguments();
    //獲取數組中的實際參數類型
    Class clzz = (Class) types[0];
    //通過實際參數類型獲取實際參數類型的實例
    model = (T) clzz.newInstance();
  } catch (InstantiationException e) {
    e.printStackTrace();
  } catch (IllegalAccessException e) {
    e.printStackTrace();
  }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM