Java獲取泛型實際類型的方法詳解
Java反射獲取
獲取類上的泛型
獲取父類定義的泛型
例如現(xiàn)在有一個父類
public abstract class TestClass<E> {
......
}
同時他有多個實現(xiàn)類,如
public class TestStringClass extends TestClass<String>{
....
}
public class TestIntegerClass extends TestClass<Integer>{
....
}
....
此時如果要獲取該類上聲明的泛型
需要用到Class類中的getGenericSuperclass方法
getGenericSuperclass方法的作用是:
返回該class所表示的實體(類、接口、原始類型或void)的直接父類的Type。如果父類是參數(shù)化類型(即有泛型定義),那么返回的Type對象必須準確的反應源代碼中使用的實際類型參數(shù)。
如果是帶有泛型的父類,則會返回ParameterizedType,如果當前Class是Object類,接口,原始類型或者void,則會返回null。
如果此對象表示數(shù)組類,則返回表示Object類的Class對象。
ParameterizedType類有3個方法,其中getActualTypeArguments能獲取到泛型列表的數(shù)組。
那么在父類中,如果要獲取子類聲明的泛型類型,就可以使用此方法
Type genericSuperclass = this.getClass().getGenericSuperclass();
if (genericSuperclass instanceof ParameterizedType){
ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
如此一來,就可以獲取到父類的泛型了。
public abstract class TestClass<E> {
public void print(){
Type genericSuperclass = this.getClass().getGenericSuperclass();
List<Type> list = null;
if (genericSuperclass instanceof ParameterizedType){
ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
list = Arrays.asList(actualTypeArguments);
}
System.out.println(this.getClass() + " 的泛型 = " + list);
}
}
public class TestStringClass extends TestClass<String>{
public static void main(String[] args) {
TestStringClass testStringClass = new TestStringClass();
testStringClass.print();
}
}
// class xxx.TestStringClass 的泛型 = [class java.lang.String]
public class TestMapClass extends TestClass<Map<String,String>>{
public static void main(String[] args) {
TestMapClass testMapClass = new TestMapClass();
testMapClass.print();
}
}
// class xxx.TestMapClass 的泛型 = [java.util.Map<java.lang.String, java.lang.String>]
如果我們想獲取泛型中的泛型,例如上面的TestClass<Map<String,String>>中的Map的泛型。
我們可以看到ParameterizedType有很多實現(xiàn)類,其中java原生的實現(xiàn)類為sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
這個實現(xiàn)類中也有一個actualTypeArguments屬性,也就是說,可以繼續(xù)嘗試獲取泛型列表
獲取接口定義的泛型
很多的接口上也定義了泛型描述,可以通過Class的getGenericInterfaces方法獲取,因為一個類可以實現(xiàn)多個接口,所以返回了一個Type數(shù)組,可以遍歷數(shù)組,找到需要處理的接口對應的Type,其余的操作就獲取父類上的泛型操作一致了。
獲取屬性的泛型
獲取屬性的泛型,先通過Class,獲取到需要獲取泛型的Field,然后過個Field類的getGenericType方法獲取到Type,其余操作與獲取父類上的泛型操作一致。
通過Spring工具類獲取
spring-core工程中,提供了一個ResolvableType工具類,他可以從屬性、方法參數(shù)、方法返回、類中后去對應的泛型。從Spring4.0開始提供這個工具類。
常用的方法有
- forField(Field field) 獲取屬性的泛型
- forMethodParameter(Method method, int parameterIndex) 獲取方法指定參數(shù)的泛型
- forMethodReturnType(Method method) 獲取方法返回值的泛型
- forConstructorParameter(Constructor constructor, int parameterIndex) 獲取構造函數(shù)指定參數(shù)的泛型
- forClass(Class clazz) 獲取class的泛型
- forType(Type type) 獲取type的泛型
- forInstance(Object) 通過實體獲取泛型
官方示例:
private HashMap<Integer, List<String>> myMap;
public void example() {
ResolvableType t = ResolvableType.forField(getClass().getDeclaredField("myMap"));
t.getSuperType(); // AbstractMap<Integer, List<String>>
t.asMap(); // Map<Integer, List<String>>
// 獲取指定下標的泛型類型
t.getGeneric(0).resolve(); // Integer
t.getGeneric(1).resolve(); // List
t.getGeneric(1); // List<String>
// 獲取指定下標的泛型的指定下標的泛型,即獲取嵌套泛型的泛型
t.resolveGeneric(1, 0); // String
}
到此這篇關于Java獲取泛型實際類型的方法詳解的文章就介紹到這了,更多相關Java獲取泛型實際類型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java實現(xiàn)將json數(shù)組轉(zhuǎn)換成對象列表的三種實現(xiàn)方法
在Java中,將JSON數(shù)組轉(zhuǎn)換為對象列表通常需要借助第三方JSON處理庫,常用的庫包括 Jackson、Gson 和 Fastjson,以下是各庫的詳細實現(xiàn)步驟,大家可以根據(jù)需要進行選擇2025-12-12
Java?spring注解@PostConstruct實戰(zhàn)案例講解
我們在Spring項目中經(jīng)常會遇到@PostConstruct注解,可能有的伙伴對這個注解很陌生,下面這篇文章主要給大家介紹了關于Java?spring注解@PostConstruct實戰(zhàn)案例講解的相關資料,需要的朋友可以參考下2023-12-12
JAVA基本類型包裝類 BigDecimal BigInteger 的使用
Java 中預定義了八種基本數(shù)據(jù)類型,包括:byte,int,long,double,float,boolean,char,short,接下來文章小編將向大家介紹其中幾個類型的內(nèi)容,需要的朋友可以參考下文章2021-09-09

