java怎樣動態(tài)獲取泛型參數(shù)的類型
Java如何動態(tài)獲取泛型參數(shù)的類型
我們都知道java中的泛型其實是偽泛型,java在編譯階段會對變異類型進行擦除,擦出到泛型類的最小上限,編譯后得到的class文件里面是沒有任何泛型信息的,泛型的控制其實就是java編譯器進行的控制,編譯階段進行泛型檢查。
那如果我們想在運行時知道泛型類的類型,如何做到呢?
主要用到下面幾個api:
1、public Type getGenericSuperclass()---Class類的方法
2、Type[] getActualTypeArguments()---ParameterizedType方法
3、public Type[] getGenericInterfaces()---Class類的方法
- 我們先定義一個泛型類:
public class Father<T> { }
- 再定義一個子類:
public class Son extends Father<String>{ }
- 先來看看下面代碼:
System.out.println(Son.class.getGenericSuperclass()); System.out.println(Son.class.getSuperclass()); System.out.println(Father.class.getGenericSuperclass()); System.out.println(Father.class.getSuperclass());
運行結(jié)果如下:
從上面運行結(jié)果可以看出兩點:
(1)通過Class類的getGenericSuperclass()是可以獲取到泛型信息的;
(2)泛型類本身是無法獲取到泛型信息的,只能通過泛型類的子類來獲取泛型信息,這也很好解釋,因為泛型類比如Father類自身,其泛型參數(shù)并未確定,自然無法獲取泛型信息,而子類的泛型參數(shù)類型已經(jīng)確定,父類泛型信息已經(jīng)確定,所以可以查詢。
具體的查詢泛型參數(shù)類型的代碼如下:
ParameterizedType parameterizedType = (ParameterizedType) Son.class.getGenericSuperclass(); System.out.println(parameterizedType.getClass().getName()); System.out.println(parameterizedType); Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); for(Type actualTypeArgument: actualTypeArguments) { System.out.println(actualTypeArgument.getClass().getName()); System.out.println(actualTypeArgument); }
運行結(jié)果如下:
由上圖運行結(jié)果可知:
(1)getGenericSuperclass()返回的實際類型為ParameterizedTypeImpl,這里面帶有父類的泛型類型信息;
(2)獲取泛型參數(shù)信息是通過ParameterizedType的getActualTypeArguments方法,該方法返回的是一個Type類型的數(shù)據(jù),該數(shù)據(jù)存放的數(shù)據(jù)的實際類型為Class,也就是我們得到了泛型參數(shù)的類信息。
上面講述的是獲取父類的泛型類型,那接口的泛型類型如何獲取呢?
- 先貼一個簡單的接口:
public interface ITest<T> { }
- 我們讓Son類實現(xiàn)該方法:
public class Son extends Father<String> implements ITest<Integer>{ }
- 獲取ITest的泛型參數(shù)類型的方法如下:
ParameterizedType parameterizedType = (ParameterizedType) Son.class.getGenericInterfaces()[0]; System.out.println(parameterizedType.getClass().getName()); System.out.println(parameterizedType); Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); for(Type actualTypeArgument: actualTypeArguments) { System.out.println(actualTypeArgument.getClass().getName()); System.out.println(actualTypeArgument); }
運行結(jié)果如下:
和泛型類區(qū)別就是getGenericSuperclass()方法換成了getGenericInterfaces(),getGenericInterfaces()方法返回的是Type[],因為一個類可以實現(xiàn)多個接口,所以想要獲取哪個接口的泛型信息,需要指定數(shù)據(jù)下標,這里Son類就實現(xiàn)了一個接口,所以直接Son.class.getGenericInterfaces()[0]就可以了。
上面的代碼有一個共同點
就是泛型類或者泛型接口已經(jīng)有一個子類了,通過子類的Class信息可以獲取到泛型父類或者泛型接口的泛型類型信息,那么如果沒有子類,怎么直接獲取泛型類的泛型類型信息呢?
很簡單,通過匿名內(nèi)部類(其實還是通過子類).
new Father<Integer>() {}.getClass().getGenericSuperclass(); new ITest<Integer>() {}.getClass().getGenericInterfaces())[0];
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java類型轉(zhuǎn)換valueOf與parseInt區(qū)別探討解析
這篇文章主要為大家介紹了Java類型轉(zhuǎn)換valueOf與parseInt區(qū)別探討解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09初學者易上手的SSH-struts2 01環(huán)境搭建(圖文教程)
下面小編就為大家?guī)硪黄鯇W者易上手的SSH-struts2 01環(huán)境搭建(圖文教程)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10JDBC插入數(shù)據(jù)返回數(shù)據(jù)主鍵代碼實例
這篇文章主要介紹了JDBC插入數(shù)據(jù)返回數(shù)據(jù)主鍵代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-11-11