Java通過反射獲取泛型實際類型總結(什麼可獲取,什麼不可獲取)

Type接口說明

Type接口只有一個實現類Class,但是有四個子接口,這四個Type子接口描述了Java泛型的四種形式。分別是:

GenericArrayType 該接口表示一種數組類型,其組件類型爲參數化類型或類型變量,如參數化類型數組Map<String, String>[] map,還有類型變量數組T[] t

ParameterizedType 該接口表示參數化類型,如 Collection<String>。

TypeVariable<T> 該接口是各種類型變量的公共高級接口,可以表示泛型聲明的參數類型(不存在的類型),如 class ClassName<T>和Collection<T>,

這裏的T就是一個類型變量。

WildcardType 表示一個通配符類型表達式,如 ?、? extends Number 或 ? super Integer。


什麼樣的泛型類型可被反射獲取?

1、類型變量和類型變量數組還有通配符類型表達式都是取不到泛型參數的實際類型的(下面說的繼承方法除外)

2、泛型的參數化類型和參數化類型數組中的實際類型可以得到實際類型,並可用於實例化。

什麼情況下可以獲取到泛型?

1、 類成員變量類型的泛型參數。

public class Test{

	private Map<String, Integer> map = new HashMap<String,Integer>();
	
	public static void main(String[] args) throws Exception {

		Field field = SapTest.class.getDeclaredField("map");
		field.setAccessible(true);
		Type genericType = field.getGenericType();
		if(genericType instanceof ParameterizedType){
			ParameterizedType parameterizedType = (ParameterizedType)genericType;
			System.out.println(parameterizedType.getActualTypeArguments());
		}
	}	
}


 2、類成員方法返回值的泛型參數。

public class Test{
	
	public static void main(String[] args) throws Exception {

		
		Method method = SapTest.class.getDeclaredMethod("test", List.class);		
		Type genericReturnType = method.getGenericReturnType();
		System.out.println("genericReturnType="+genericReturnType);
		if(genericReturnType instanceof ParameterizedType){
			System.out.println(((ParameterizedType)(genericReturnType)).getActualTypeArguments()[0]);
		}
	}
	
	public List<Integer> test(List<String> t){
		return new ArrayList<Integer>();
	}


 3、類成員方法參數類型的泛型參數。

public class Test{
	
	public static void main(String[] args) throws Exception {
	
		Method method = SapTest.class.getDeclaredMethod("test", List.class);		
		Type[] genericParameterTypes = method.getGenericParameterTypes();
		if(genericParameterTypes[0] instanceof ParameterizedType){
			System.out.println(((ParameterizedType)(genericParameterTypes[0])).getActualTypeArguments()[0]);
		}
	}
	
	public List<Integer> test(List<String> t){
		return new ArrayList<Integer>();
	}


 4、類構造函數的參數類型的泛型參數。

public class Test{

	public Test(List<String> list){

       }
	
	public static void main(String[] args) {
		
		Constructor<SapTest> constructor = SapTest.class.getConstructor(List.class);
		Type[] genericParameterTypes = constructor.getGenericParameterTypes();
		Type type = ((ParameterizedType)(genericParameterTypes[0])).getActualTypeArguments()[0];
		System.out.println(type);
         }
}

 5、通過extends在子類指定父類中泛型變量具體類型的,可獲取父類泛型的具體類型  

class Father<T>{
     public Father(){
         Type genType = getClass().getGenericSuperclass();  
     Type params = ((ParameterizedType)genType).getActualTypeArguments()[0]; 
     }
}
class Children extends Father<Children>{}

這是目前我所知道的可以獲取到泛型的實際類型的五種情況,如果還有別的情況,希望大家留言指正。

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