日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

深入分析JAVA 反射和泛型

瀏覽:106日期:2022-08-30 16:33:28

從 JDK5 以后,Java 的 Class 類增加了泛型功能,從而允許使用泛型來限制 Class 類,例如,String.class 的類型實際上是 Class<String>。如果 Class 對應的類暫時未知,則使用 Class<?>。通過在反射中使用泛型,可以避兔使用反射生成的對象需要強制類型轉換。

泛型和 Class 類

使用 Class<T> 泛型可以避免強制類型轉換。例如,下面提供一個簡單的對象工廠,該對象工廠可以根據指定類來提供該類的實例。

public class CrazyitObjectFactory { public static Object getInstance(String clsName) { try { // 創建指定類對應的Class對象 Class cls = Class.forName(clsName); // 返回使用該Class對象所創建的實例 return cls.newInstance(); } catch (Exception e) { e.printStackTrace(); return null; } }}

上面程序中兩行粗體字代碼根據指定的字符串類型創建了一個新對象,但這個對象的類型是 Object,因此當需要使用 CrazyitObjectFactory 的 getInstance() 方法來創建對象時,將會看到如下代碼:

// 獲取實例后需要強制類型轉換Date d = (Date)Crazyit.getInstance('java.util.Date');

甚至出現如下代碼:

JFrame f = (JFrame)Crazyit.getInstance('java.util.Date');

上面代碼在編譯時不會有任何問題,但運行時將拋出 ClassCastException 異常,因為程序試圖將一個 Date 對象轉換成 JFrame 對象。

如果將上面的 CrazyitObjectFactory 工廠類改寫成使用泛型后的 Class,就可以避免這種情況。

public class CrazyitObjectFactory2 { public static <T> T getInstance(Class<T> cls) { try { return cls.newInstance(); } catch (Exception e) { e.printStackTrace(); return null; } } public static void main(String[] args) { // 獲取實例后無須類型轉換 Date d = CrazyitObjectFactory2.getInstance(Date.class); JFrame f = CrazyitObjectFactory2.getInstance(JFrame.class); }}

在上面程序的 getInstance() 方法中傳入一個 Class<T> 參數,這是一個泛型化的 Class 對象,調用該 Class 對象的 newInstance() 方法將返回一個 T 對象,如程序中粗體字代碼所示。接下來當使用 CrazyitObjectFactory2 工廠類的 getInstance() 方法來產生對象時,無須使用強制類型轉換,系統會執行更嚴格的檢查,不會出現 ClassCastException 運行時異常。

前面介紹使用 Array 類來創建數組時,曾經看到如下代碼:

// 使用 Array 的 newInstance 方法來創建一個數組Object arr = Array.newInstance(String.class, 10);

對于上面的代碼其實使用并不是非常方便,因為 newInstance() 方法返回的確實是一個 String[] 數組,而不是簡單的 Object 對象。如果需要將對象當成 String[] 數組使用,則必須使用強制類型轉換——這是不安全的操作。

為了示范泛型的優勢,可以對 Array 的 newInstance() 方法進行包裝。

public class CrazyitArray { // 對Array的newInstance方法進行包裝 @SuppressWarnings('unchecked') public static <T> T[] newInstance(Class<T> componentType, int length) { return (T[]) Array.newInstance(componentType, length); // ① } public static void main(String[] args) { // 使用CrazyitArray的newInstance()創建一維數組 String[] arr = CrazyitArray.newInstance(String.class, 10); // 使用CrazyitArray的newInstance()創建二維數組 // 在這種情況下,只要設置數組元素的類型是int[]即可。 int[][] intArr = CrazyitArray.newInstance(int[].class, 5); arr[5] = '瘋狂Java講義'; // intArr是二維數組,初始化該數組的第二個數組元素 // 二維數組的元素必須是一維數組 intArr[1] = new int[] { 23, 12 }; System.out.println(arr[5]); System.out.println(intArr[1][1]); }}

上面程序中粗體字代碼定義的 newInstance() 方法對 Array 類提供的 newInstance() 方法進行了包裝,將方法簽名改成了 public static <T> T[] newInstance(Class<T> componentType, int length),這就保證程序通過該 newInstance() 方法創建數組時的返回值就是數組對象,而不是 Object 對象,從而避免了強制類型轉換。

提示:程序在①行代碼處將會有一個 unchecked 編譯警告,所以程序使用了 @SuppressWarnings 來抑制這個警告信息。

使用反射來獲取泛型信息

通過指定類對應的 Class 對象,可以獲得該類里包含的所有成員變量,不管該成員變量是使用 private 修飾,還是使用 public 修飾。獲得了成員變量對應的 Field 對象后,就可以很容易地獲得該成員變量的數據類型,即使用如下代碼即可獲得指定成員變量的類型。

// 獲取成員變量 f 的類型Class<?> a = f.getType();

但這種方式只對普通類型的成員變量有效。如果該成員變量的類型是有泛型類型的類型,如 Map<String, Integer> 類型,則不能誰確地得到該成員變量的泛型參數。

為了獲得指定成員變量的泛型類型,應先使用如下方法來獲取該成員變量的泛型類型。

// 獲得成員變量 f 的泛型類型Type gType = f.getGenericType();

然后將 Type 對象強制類型轉換為 ParameterizedType 對象,ParameterizedType 代表被參數化的類型,也就是增加了泛型限制的類型。ParameterizedType 類提供了如下兩個方法。

getRawType():返回沒有泛型信息的原始類型。 getActualTypeArguments():返回泛型參數的類型。

下面是一個獲取泛型類型的完整程序。

public class GenericTest { private Map<String, Integer> score; public static void main(String[] args) throws Exception { Class<GenericTest> clazz = GenericTest.class; Field f = clazz.getDeclaredField('score'); // 直接使用getType()取出的類型只對普通類型的成員變量有效 Class<?> a = f.getType(); // 下面將看到僅輸出java.util.Map System.out.println('score的類型是:' + a); // 獲得成員變量f的泛型類型 Type gType = f.getGenericType(); // 如果gType類型是ParameterizedType對象 if (gType instanceof ParameterizedType) { // 強制類型轉換 ParameterizedType pType = (ParameterizedType) gType; // 獲取原始類型 Type rType = pType.getRawType(); System.out.println('原始類型是:' + rType); // 取得泛型類型的泛型參數 Type[] tArgs = pType.getActualTypeArguments(); System.out.println('泛型信息是:'); for (int i = 0; i < tArgs.length; i++) {System.out.println('第' + i + '個泛型類型是:' + tArgs[i]); } } else { System.out.println('獲取泛型類型出錯!'); } }}

上面程序中的粗體字代碼就是取得泛型類型的關鍵代碼。運行上面程序,將看到如下運行結果:

score的類型是:interface java.util.Map原始類型是:interface java.util.Map泛型信息是:第0個泛型類型是:class java.lang.String第1個泛型類型是:class java.lang.Integer

從上面的運行結果可以看出,使用 getType() 方法只能獲取普通類型的成員變量的數據類型:對于增加了泛型的成員變量,應該使用 getGenericType() 方法來取得其類型。

提示:Type 也是 java.lang.reflect 包下的一個接口,該接口代表所有類型的公共高級接口,Class 是 Type 接口的實現類。Type 包括原始類型、參數化類型、數組類型、類型變量和基本類型等。

以上就是深入分析JAVA 反射和泛型的詳細內容,更多關于JAVA 反射和泛型的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
欧美.日韩.国产.一区.二区 | 亚洲精品1区| 人人精品亚洲| 日韩高清欧美激情| 亚洲黄色免费看| 三级亚洲高清视频| 牛牛精品成人免费视频| 成人在线视频中文字幕| 天堂成人国产精品一区| 国产精品久一| 99久久精品网| 国产精品porn| 亚洲少妇在线| 亚洲三级av| 一区二区三区四区日本视频| 一区二区电影在线观看| 日韩福利一区| 国产极品模特精品一二| 亚洲色图国产| 亚洲爱爱视频| 精品少妇av| 久久精品99国产国产精| 亚洲精品123区| 亚洲成av在线| 精品一区二区三区免费看| 日本不卡一区二区三区| 免费国产自久久久久三四区久久 | 日韩精品视频网站| 激情综合网站| 久久91导航| 国产成人精品一区二区免费看京 | 日韩在线精品| 久久国产精品99国产| 性感美女一区二区在线观看| 最新国产精品久久久| 久久精品卡一| 美女久久久精品| 在线午夜精品| 国产成人精品亚洲线观看| 午夜欧美视频| 色偷偷偷在线视频播放| 日韩欧美精品一区二区综合视频| 国产精品久久久久久久久妇女| 亚洲三级毛片| 好看不卡的中文字幕| 亚洲二区在线| 亚洲视频综合| 亚洲欧美日韩高清在线| 日韩精品水蜜桃| a国产在线视频| 欧美日韩国产观看视频| 麻豆高清免费国产一区| 国产香蕉精品| 日韩一区二区免费看| 欧美日韩水蜜桃| 激情欧美一区| 视频一区视频二区在线观看| 亚洲午夜精品久久久久久app| 国产精品久久久久久久免费观看| 精品亚洲a∨| 69堂精品视频在线播放| 亚洲午夜久久| 婷婷综合国产| 国产色99精品9i| 国产精品极品| 福利一区二区| 欧美日韩在线观看视频小说| 亚洲女同av| 日韩av在线播放网址| 在线天堂中文资源最新版| 精品成人免费一区二区在线播放| 欧美成人a交片免费看| 日本一区二区高清不卡| 1024精品一区二区三区| 久久国产精品99国产| 在线综合欧美| 日本a级不卡| 国产三级一区| 欧洲一级精品| 日韩一区二区三区精品| 国产精品a久久久久| 韩国精品主播一区二区在线观看 | 亚洲va久久| 日韩精品一页| 久久久精品网| 精品久久久中文字幕| 日韩精品一区第一页| 亚洲不卡系列| 亚洲精品麻豆| 亚洲精品伊人| 色网在线免费观看| 精品三级国产| 久久久久国产| 亚洲成人精选| 日韩精品中文字幕一区二区| 人人精品久久| 视频在线在亚洲| 国产99久久| аⅴ资源天堂资源库在线| 国产欧美二区| 日本成人在线网站| 亚洲v天堂v手机在线| 狠狠干综合网| 91高清一区| 久久久人人人| 五月天av在线| 国产黄大片在线观看| 久久这里只有精品一区二区| 快she精品国产999| 99久久99久久精品国产片果冰| 成人一区而且| 国产欧洲在线| 成人免费电影网址| 91亚洲一区| 亚洲国产成人二区| 天堂av在线| 日韩大片在线播放| 99久久99久久精品国产片果冰 | 激情丁香综合| 亚洲国产成人二区| 色综合五月天| 涩涩涩久久久成人精品| 国产亚洲激情| 精品国产亚洲一区二区三区大结局 | 国产成人精品一区二区免费看京 | 日韩av黄色在线| 在线看片福利| 国产精品17p| 97久久中文字幕| 日韩综合一区二区| 涩涩涩久久久成人精品| 日韩中文字幕av电影| 国产精品色网| 亚洲尤物av| 国产探花一区在线观看| 日韩国产欧美视频| 国产精品日韩精品在线播放| 国产精品天天看天天狠| 欧美欧美黄在线二区| 国产精品视频一区二区三区四蜜臂| 免费成人在线影院| 九一国产精品| 欧美精品九九| 香蕉久久久久久久av网站| 亚洲综合专区| 国产剧情一区| 日韩深夜视频| 91久久午夜| 欧美亚洲三级| 精品视频高潮| 91超碰国产精品| 欧美一区二区三区久久| www.com.cn成人| 亚洲免费影视| 久久99青青| 99热精品久久| 久久国产欧美| 亚洲精品婷婷| 欧美激情日韩| 欧美日韩一区二区三区视频播放| 1024精品久久久久久久久| 亚洲精品一二三**| www.九色在线| 日韩免费精品| 欧美特黄一级大片| 国产精品欧美在线观看| 亚洲激情黄色| 国产精品原创| 国产精品高清一区二区| 久久福利一区| 91精品蜜臀一区二区三区在线| 丝袜诱惑一区二区| 国产欧美一区二区三区国产幕精品 | 卡一卡二国产精品| 欧美丝袜一区| 久久久久久色 | 电影91久久久| 日韩欧美三区| 野花国产精品入口| 欧美在线91| 亚洲欧美网站| 最新中文字幕在线播放| 亚洲欧美网站| 久久国产精品成人免费观看的软件| 欧美在线亚洲综合一区| 日韩高清二区| 国产91在线播放精品| 欧美a在线观看| 国产一卡不卡| 91成人福利| 日韩成人av影视| 日韩高清在线一区| 日韩高清成人在线| 91国内精品| 一区二区三区四区日韩| 成人看片网站| 久久精品国产68国产精品亚洲| 精品捆绑调教一区二区三区| 中文字幕在线看片| 久久婷婷丁香|