spring更好的處理泛型
阿新 • • 發佈:2019-02-05
由於泛型擦除,使得Generic無法獲取自己的Generic的Type型別。實際上BadClass()例項化以後Class裡面就不包括T的資訊了,對於Class而言T已經被擦拭為Object,而真正的T引數被轉到使用T的方法(或者變數宣告或者其它使用T的地方)裡面(如果沒有那就沒有存根),所以無法反射到T的具體類別,也就無法得到T.class。 而getGenericSuperclass()是Generic繼承的特例,對於這種情況子類會儲存父類的Generic引數型別,返回一個ParameterizedType,這時可以獲取到父類的T.class了,這也正是子類確定應該繼承什麼T的方法
傳統Java方式獲取泛型資訊
繼承的父類是泛型(class.getGenericSuperclass())
用到的類
public class Person<T> { } public class Student extends Person<String> { }
- 測試程式碼
@Test
public void test01() {
// 對於繼承的父類是泛型的情況
ParameterizedType genericSuperclass = (ParameterizedType) Student.class.getGenericSuperclass ();
System.out.println(genericSuperclass);
Type type = genericSuperclass.getActualTypeArguments()[0];
System.out.println(type);
System.out.println();
}
- 執行結果
com.fanxing.Person<java.lang.String>
class java.lang.String
實現的介面是泛型
用到的類
public interface IDAO<T> { } public
- 測試程式碼
@Test
public void test02() {
// 對於實現的介面是泛型的處理情況
ParameterizedType parameterizedType = (ParameterizedType) StringDao.class.getGenericInterfaces()[0];
System.out.println(parameterizedType);
Type genericType = parameterizedType.getActualTypeArguments()[0];
System.out.println(genericType);
System.out.println();
}
- 執行結果
com.fanxing.IDAO<java.lang.String>
class java.lang.String
使用Spring的ResolvableType獲取泛型資訊
繼承的父類是泛型
- 測試程式碼
@Test
public void test04() {
// Spring的提供工具類,用於獲取繼承的父類是泛型的資訊
ResolvableType resolvableType = ResolvableType.forClass(Student.class);
System.out.println(resolvableType);
Class<?> resolve = resolvableType.getSuperType().getGeneric(0).resolve();
System.out.println(resolve);
}
- 執行結果
com.fanxing.Student
class java.lang.String
實現的介面是泛型
- 測試程式碼
@Test
public void test03() {
// Spring的提供工具類,用於獲取實現的介面是泛型的資訊
ResolvableType resolvableType = ResolvableType.forClass(StringDao.class);
System.out.println(resolvableType);
Class<?> resolve = resolvableType.getInterfaces()[0].getGeneric(0).resolve();
System.out.println(resolve);
}
- 執行結果
com.fanxing.StringDao
class java.lang.String
得到欄位級別的泛型資訊
用到的Java類
package com.fanxing;
import java.util.List;
import java.util.Map;
public class GenericClass {
private List<String> listString;
private List<List<String>> listLists;
private Map<String, Long> maps;
private Person<String> persons;
public GenericClass() {
}
public List<String> getListString() {
return listString;
}
public void setListString(List<String> listString) {
this.listString = listString;
}
public Map<String, Long> getMaps() {
return maps;
}
public void setMaps(Map<String, Long> maps) {
this.maps = maps;
}
public Person<String> getPersons() {
return persons;
}
public void setPersons(Person<String> persons) {
this.persons = persons;
}
public List<List<String>> getListLists() {
return listLists;
}
public void setListLists(List<List<String>> listLists) {
this.listLists = listLists;
}
}
自定義的泛型資訊
- 測試程式碼
// Spring的提供工具類,用於欄位的泛型資訊,Person<String>
ResolvableType resolvableType = ResolvableType.forField(ReflectionUtils.findField(GenericClass.class, "persons"));
System.out.println(resolvableType);
// 然後通過如下API得到Person<String>的第0個位置上的泛型實參型別,即String
Class<?> resolve = resolvableType.getGeneric(0).resolve();
System.out.println(resolve);
- 輸出結果
com.fanxing.Person<java.lang.String>
class java.lang.String
獲取List屬性的泛型
List< String >的情況
- 測試程式碼
ResolvableType resolvableType = ResolvableType.forField(ReflectionUtils.findField(GenericClass.class, "listString"));
System.out.println(resolvableType);
// 然後通過如下API得到Person<String>的第0個位置上的泛型實參型別,即String
Class<?> resolve = resolvableType.getGeneric(0).resolve();
System.out.println(resolve);
- 執行結果
java.util.List<java.lang.String>
class java.lang.String
List< List < String > > 的情況
- 測試程式碼
@Test
public void test07() {
// Spring的提供工具類,用於欄位的泛型資訊,List<List<String>>
ResolvableType resolvableType = ResolvableType.forField(ReflectionUtils.findField(GenericClass.class, "listLists"));
System.out.println(resolvableType);
// 然後通過如下API得到Person<String>的第0個位置上的泛型實參型別,即String
// Class<?> resolve =
// resolvableType.getGeneric(0).getGeneric(0).resolve();
Class<?> resolve = resolvableType.getGeneric(0, 0).resolve();
System.out.println(resolve);
}
- 輸出結果
java.util.List<java.util.List<java.lang.String>>
class java.lang.String
獲取Map屬性的泛型
- 測試程式碼
@Test
public void test08() {
// Spring的提供工具類,用於欄位的泛型資訊,List<List<String>>
ResolvableType resolvableType = ResolvableType//
.forField(ReflectionUtils.findField(GenericClass.class, "maps"));
System.out.println(resolvableType);
// 然後通過如下API得到Person<String>的第0個位置上的泛型實參型別,即String
Class<?> resolve = resolvableType.getGeneric(0).resolve();
System.out.println(resolve);
}
- 執行結果
java.util.Map<java.lang.String, java.lang.Long>
class java.lang.String
得到方法返回值的泛型資訊
- 測試程式碼
@Test
public void test09() {
// Spring的提供工具類,用於方法的返回值的泛型資訊,Map<String, Long>
ResolvableType resolvableType = ResolvableType.forMethodReturnType(ReflectionUtils.findMethod(GenericClass.class, "getMaps"));
Class<?> resolve = resolvableType.getGeneric(1).resolve();
System.out.println(resolve);
}
- 執行結果
@Test
public void test09() {
// Spring的提供工具類,用於方法的返回值的泛型資訊,Map<String, Long>
ResolvableType resolvableType = ResolvableType.forMethodReturnType(ReflectionUtils.findMethod(GenericClass.class, "getMaps"));
Class<?> resolve = resolvableType.getGeneric(1).resolve();
System.out.println(resolve);
}
參考的部落格地址
http://jinnianshilongnian.iteye.com/blog/1993608