泛型的術語
<>
: 念做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
舉例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();
}
}