日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java进阶 | 泛型机制与反射原理

發布時間:2025/3/16 java 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java进阶 | 泛型机制与反射原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、泛型的概念

1、基礎案例

泛型在Java中的應用非常廣泛,最常見則是在集合容器中,先看下基礎用法:

public class Generic01 {public static void main(String[] args) {Map<Integer,String> map = new HashMap<>() ;map.put(88,"hello") ;// map.put("99","world") ; 輸入編譯錯誤String value = map.get(88) ;// Integer value = map.get(88) ; 輸出編譯錯誤System.out.println("value:"+value);} }

聲明一個map類型的容器,并且明確限定key和value的類型:分別為Integer,String,這樣顯然不能體現特別之處,可以對比下面的用法:

Map newMap = new HashMap() ; newMap.put("hello","world"); newMap.put(88,99);

在不指定類型的情況下,鍵值對都默認為Object類型,這樣的容器在使用的時候要時刻注意不同的key類型和取出的value值類型,并且value要做類型轉換,相比之下泛型機制就很有必要。

可以看下Map接口的定義:

public interface Map<K,V> {V get(Object key);V put(K key, V value); }

在Map接口中,<K,V>顯然沒有指定明確的類型,只是起到類型傳遞的作用,即K是key的類型,V是value的類型,在上面的源碼中描述的很清楚,結合上面案例,在Map對象聲明的時候可以明確指定<K,V>的類型,也可以缺省為Object類型。

2、泛型描述

泛型即可以理解為把數據類型作為參數,即參數化類型,用來提高代碼的安全性,靈活性,避免類型轉換;代碼簡潔明了,同時對于程序的可擴展性起到至關重要的作用。

首先設計一個簡單的頂層接口,只定義一個callBack方法,和對出入參數的簡單邏輯設定,這種設計在Java的源碼設計中隨處可見,例如上面的集合體系:

/*** 基礎接口設計* @param <R> 返參類型* @param <V> 入參類型*/ interface CallBack<R,V> {/*** 回調方法:V 方法入參 ,R 方法返回值*/R callBack (V v) ; }

為了實現具體的業務,再基于頂層接口向下做擴展,這里聲明兩個擴展接口,作為具體業務類的接口:

/*** 擴展接口設計01*/ interface ExtCallBack01<R extends Integer,V extends List<String>>extends CallBack<Integer,List<String>> {@OverrideInteger callBack (List<String> list) ; } /*** 擴展接口設計01*/ interface ExtCallBack02<R extends Boolean,V extends Map<String,Long>>extends CallBack<Boolean,Map<String,Long>> {@OverrideBoolean callBack (Map<String,Long> map) ; }

這樣可以通過擴展接口去設計具體的業務類,提高程序的靈活可擴展性:

public class Generic02 {public static void main(String[] args) {new ExtCallBack01<Integer,List<String>>(){@Overridepublic Integer callBack(List<String> list) {list.add("hello");return list.size();}};new ExtCallBack02<Boolean,Map<String,Long>> (){@Overridepublic Boolean callBack(Map<String, Long> map) {map.put("Fire",119L) ;return map.size()>0 ;}} ;} }

通過上面這個案例,可以清楚的感覺到泛型機制的靈活和強大。

3、泛型本質

泛型雖然可以使用在類,接口,方法,參數等各個地方,但是其約束能力是在代碼的編譯期:

public class Generic03 {public static void main(String[] args) {DefEntry<String> defEntry1 = new DefEntry<>("hello") ;DefEntry<Long> defEntry2 = new DefEntry<>(999L) ;// Always TrueSystem.out.println(defEntry1.getClass()==defEntry2.getClass());} } class DefEntry<T> {private T param ;public DefEntry (T param){this.param = param ;} }

編譯過程中,會對泛型合法性作校驗,校驗成功編譯的class文件沒有泛型信息,即泛型擦除掉,通過一個簡單的命令查看編譯后的文件:

javap -v Generic03.class

當然這也會帶來安全問題:

public static void main(String[] args) throws Exception {Map<String, String> map = new HashMap<>();Method method = HashMap.class.getDeclaredMethod("put",new Class[] { Object.class, Object.class });method.invoke(map,888L, 999L);// {888=999}System.out.println(map);// java.lang.ClassCastExceptionSystem.out.println(map.get(888L)); }

這里即通過反射的機制,繞開泛型,在map中放入程序語義上的非法值類型,在運行過程中獲取值的時候才拋出類型轉換異常。

二、反射機制

1、基礎描述

反射機制可以在程序運行時獲取類的完整結構信息,并且可以動態的操作屬性和方法等。

對于反射機制的理解,必須要對類編譯和JVM加載,運行時數據區有清楚的認識,這塊內容可以移步JVM系列的文章。

通過運行時動態獲取類的結構,然后動態的創建對象并操作屬性和方法,這種方式在實際開發中并不多用,這樣很明顯會消耗JVM資源,并且會忽略一些封裝導致安全問題,這在上面【1】中已經案例說明了。

2、反射的類庫

  • java.lang.Class:Class類
  • java.lang.reflect.Constructor:構造器
  • java.lang.reflect.Field:屬性
  • java.lang.reflect.Method:方法

API之Class對象

獲取目標類型的Class對象常見方式,通過Class對象再獲取相關結構信息,從而操作或者訪問:

public static void main(String[] args) throws Exception {// Class對象回去User user1 = new User(1,"name01") ;Class userClass1 = user1.getClass() ;Class userClass2 = Class.forName("com.java.reflect.User");Class userClass3 = User.class ;System.out.println(User.class.getName());System.out.println("userClass1==userClass2?"+(userClass1==userClass2));System.out.println("userClass2==userClass3?"+(userClass2==userClass3));// 類型創建和判斷Object object = User.class.newInstance() ;System.out.println("類型:"+(object instanceof User));System.out.println("類型:"+(userClass3.isInstance(user1))); }

輸出結果:

這里有個注意點:通過Class對象的newInstance()方法,即基于User類的無參構造器,首先要求User類具有無參構造方法。

API之Constructor構造器

Class對象讀取構造方法,可以分別獲得全部構造方法,不同修飾類型的構造方法,或者根據構造參數類型指定獲取:

public static void main(String[] args) throws Exception {Class userClass = User.class ;// 讀取公共構造方法Constructor[] userConArr = userClass.getConstructors();printCon(userConArr);// 讀取指定私有構造方法Constructor privateCon = userClass.getDeclaredConstructor(Integer.class);System.out.println(privateCon);// 讀取全部構造方法userConArr = userClass.getDeclaredConstructors();printCon(userConArr);// 調用公共構造方法創建對象Constructor pubCon = userClass.getConstructor(Integer.class,String.class);Object pubUser = pubCon.newInstance(1,"hello") ;// 調用私有構造方法創建對象Constructor priCon = userClass.getDeclaredConstructor(Integer.class);// 忽略private權限修飾符priCon.setAccessible(Boolean.TRUE);Object priUser = priCon.newInstance(2) ;System.out.println(pubUser+"\n"+priUser); } public static void printCon (Constructor[] constructors){for (Constructor constructor:constructors){System.out.println(constructor);} }

這里需要注意的是,通過調用setAccessible(Boolean.TRUE)方法,可以基于私有構造方法創建對象,這里明顯違背了Java的基本設計原則,破壞代碼的安全性。

API之Field屬性

Field保證成員變量的屬性,修飾符,值管理等相關操作:

public static void main(String[] args) throws Exception {Class userClass = User.class ;// 獲取公共字段Field[] pubArr = userClass.getFields() ;printField(pubArr);// 獲取全部字段Field[] fieldArr = userClass.getDeclaredFields() ;printField(fieldArr);// 獲取指定字段Field emailField = userClass.getField("email") ;Field nameField = userClass.getDeclaredField("name") ;printField(new Field[]{emailField,nameField});// 創建對象并操作屬性Object userObj = userClass.newInstance() ;nameField.setAccessible(Boolean.TRUE);nameField.set(userObj,"world");emailField.set(userObj,"test@email.com");System.out.println("userObj:"+userObj); } /*** 打印成員變量信息*/ public static void printField (Field[] fields){for (Field field : fields){System.out.println("聲明:"+field);UserAnno userAnno = field.getAnnotation(UserAnno.class) ;System.out.println("注解:"+userAnno.desc());String fieldName = field.getName() ;System.out.println("名稱:"+fieldName);Type type = field.getGenericType() ;System.out.println("類型:"+type);} }

注意這里獲取Type類型信息,在有些特定的業務場景下還是十分有用的。

API之Method方法

public static void main(String[] args) throws Exception {Class userClass = User.class ;// 獲取所有公共方法[包括父類和Object類方法]Method[] pubMethods = userClass.getMethods() ;printMethod(pubMethods);// 獲取全部方法Method[] allMethods = userClass.getDeclaredMethods() ;printMethod(allMethods);// 獲取指定方法Method method = userClass.getMethod("parName",String.class) ;printMethod(new Method[]{method});// 調用方法Object userObj = userClass.newInstance() ;Method setId = userClass.getDeclaredMethod("setId", Integer.class);setId.invoke(userObj,99) ;Method setName = userClass.getDeclaredMethod("setName", String.class);setName.invoke(userObj,"java") ;Method sayHi = userClass.getDeclaredMethod("sayHi", String.class);sayHi.setAccessible(Boolean.TRUE);sayHi.invoke(userObj,"c++");System.out.println(userObj); } /*** 打印方法信息*/ public static void printMethod (Method[] methods){for (Method method : methods){System.out.println("定義:"+method);System.out.println("命名:"+method.getName());UserAnno userAnno = method.getAnnotation(UserAnno.class) ;if (userAnno != null){System.out.println("注解:"+userAnno.desc());}Type[] paramTypeArr = method.getParameterTypes();for (int i=0 ; i< paramTypeArr.length; i++){System.out.print("參數"+(i+1)+"類型:"+paramTypeArr[i]+" ; ");}System.out.println("參數個數:"+method.getParameterCount());} }

注意這里對方法的獲取遠遠不止類本身定義的,包括從父類繼承的,和Java基礎Object類中的。

三、源代碼地址

GitHub·地址 https://github.com/cicadasmile/java-base-parent GitEE·地址 https://gitee.com/cicadasmile/java-base-parent

閱讀標簽

【Java基礎】【設計模式】【結構與算法】【Linux系統】【數據庫】

【分布式架構】【微服務】【大數據組件】【SpringBoot進階】【Spring&Boot基礎】

【數據分析】【技術導圖】【 職場】

總結

以上是生活随笔為你收集整理的Java进阶 | 泛型机制与反射原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 少妇又色又紧又黄又刺激免费 | 色偷偷噜噜噜亚洲男人的天堂 | 精品一区二区久久久 | 日本公与丰满熄 | 在线观看网页视频 | 日韩一区二区三区四区五区六区 | 久久久.com | 光棍影院手机版在线观看免费 | 中文字幕在线视频播放 | 久久肉| 天天热天天干 | www.国产在线视频 | 成人毛片一区二区三区 | 亚洲美女网站 | 国产欧美日韩专区 | 国产日韩一区二区三区在线观看 | 瑟瑟视频在线免费观看 | 日本乱淫视频 | 成年黄色网 | 天堂无乱码 | 琪琪伦伦影院理论片 | 婷婷狠狠干 | 久久久久在线观看 | 国产一级特黄aaa大片 | 四季av国产一区二区三区 | 欧美日韩123 | 在线国产视频一区 | 一区二区三区在线免费观看 | 自拍偷拍欧美激情 | 国产欧美日韩另类 | 欧美男优 | 最新最全av网站 | a天堂在线观看视频 | 五月天综合婷婷 | jizz俄罗斯 | 国产美女自拍 | 高h校园不许穿内裤h调教 | 天堂√8在线中文 | 久久久久人妻一区精品色欧美 | 国产福利视频一区二区 | 亚洲精品午夜 | 狠狠干一区二区 | 在线看片 | 国产精品99久久久久久久女警 | 国产裸体永久免费无遮挡 | 亚洲免费一区视频 | 野外(巨肉高h) | 欧美一级免费在线 | 99国产精| av每日更新 | 五月婷婷在线观看视频 | 99久久婷婷国产精品综合 | 成人免费黄色 | 免费不卡av | 午夜激情视频在线观看 | 中文字幕一本 | 久久都是精品 | 日韩欧美精品一区二区三区 | 黑人一区| 日韩aaaaa| 中日精品一色哟哟 | www.久久国产| 久久亚洲av午夜福利精品一区 | 久久综合成人 | 国产色一区二区 | 一区二区三区四区在线播放 | 日韩一页 | 欧洲精品码一区二区三区免费看 | 最近中文在线观看 | 欧美一级片在线视频 | mm1313亚洲国产精品无码试看 | 一个人看的视频www 色就是色网站 | 日本少妇喷水 | 一级特黄视频 | www日本视频 | 日日碰狠狠添天天爽无码 | 精品人妻一区二区三区四区 | 黄色三级免费网站 | 懂色av一区二区三区四区五区 | 韩国三级中文字幕hd浴缸戏 | 韩国妻子的朋友 | www.youji.com| 日本h视频在线观看 | 日本视频在线观看 | 精品在线99| www.久色| 麻豆久久精品 | 日韩少妇内射免费播放 | 波多野结衣一区二区三区在线观看 | 日本美女影院 | 亚洲影音| 久久国产精品综合 | 国产亚洲一区二区三区在线观看 | 18禁网站免费无遮挡无码中文 | 亚洲国产精品va在线看黑人 | 色性网 | 二区在线播放 | 男女午夜激情 | 欧美久久99 |