国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

你真的了解Java的反射機制嗎?

開發 前端
今天我們說一說反射,反射不是設計模式,但是反射機制作為java的基礎之一,在眾多框架的源碼中大量使用,是很多設計模式,框架,組件的重要基礎。

書寫代碼必須符合高質量高性能要求,這也是能夠在視覺上和其他程序員拉開差距的技能,同時也是一個優秀程序員的基本要求。

  • 何為高質量:代碼具備可維護性,可讀性,可擴展性,靈活性,簡潔性,可復用性, 可測試性。
  • 何為高性能:代碼能盡可能的提高處理效率。

今天我們說一說反射,反射不是設計模式,但是反射機制作為java的基礎之一,在眾多框架的源碼中大量使用,是很多設計模式,框架,組件的重要基礎。比如我們知道的spring aop底層是jdk的動態代理,而動態代理依賴的就是反射機制。

一、反射機制

1.概念

在運行狀態中,對于任意一個類,都能知道這個類的所有屬性和方法;對于任意一個對象都能調用它的任意方法和屬性,這種動態獲取類信息以及動態調用對象方法的功能稱為Java的發射機制。

先了解下類對象的概念:

我們知道類的加載過程為加載 驗證 準備 解析 初始化 銷毀,在加載階段,jvm會根據類的全限定名找到二進制字節流,并把這個二進制字節流加載進內存,轉為運行時數據區的存儲結構,最后創建一個java.lang.Class類型的實例作為方法區這個類型的訪問入口,這里所說的Class實例就是類對象,這個類對象創建完成后會存放在堆區,這個動作是在加載階段完成。

方法區中存放的是類的元數據,包括靜態變量,有哪些屬性,有哪些方法,繼承的父類,實現的接口,異常相關的信息等等,而類對象就是這些信息的訪問入口,Class類提供了很多api,這些api大多是native方法,也就說明這個類對象只是這個類在堆區的一個接口,由jvm底層來實現,jvm底層會根據每個api的功能去方法區拿類的信息。

2.反射的應用

public static void main(String[] args) {

    UserService userService = new UserService();
    System.out.println("new關鍵字創建對象:"+userService);
    
    Class<UserService> userClass= UserService.class;
      Class userClass1= Class.forName("UserService");
      
    Constructor<?>[] constructors=userClass.getDeclaredConstructors();
    Constructor constructor=constructors[0];
    Object user=constructor.newInstance("333333","666666");
    System.out.println("反射創建對象:"+user;
}

通過上面的這個例子,我們可以看到反射是如何應用的:

  • 首先通過.class或者Class.forName()方法,獲取一個Class實例,這個實例就是類對象,
  • 然后通過調用這個Class實例的方法獲取類的構造方法,得到構造方法Constructor實例
  • 然后調用Constructor實例的newInstance方法進行實例化對象。

以上是利用反射機制創建對象,當然除了創建對象,還可以獲取類的屬性實例Field和方法實例Method,通過方法實例和屬性實例的api對對象的方法和屬性進行設置或者執行。這便是反射的應用。

3.反射的特點

new關鍵字創建對象是加載類完成后接著走創建對象過程,而反射過程是Class.forName()觸發加載類,但是不會創建對象,只有在調用newInstance方法時候才會創建對象,也就是把加載類和創建對象分為兩個部分完成,但是調用newInstance方法創建前必須保證類已經加載完成。

new關鍵字創建對象是靜態編譯,而反射創建對象是動態編譯:

  • 靜態編譯:在編譯的時候就已經知道要創建什么對象,就會把對應類加載(忽略懶加載)
  • 動態編譯:在編譯的時候不知道要創建什么對象,等到運行到這段代碼的時候才知道要創建什么對象。

比如下面的代碼,編譯階段是不知道是否要創建UserService類的對象的,所以UserService不會被加載:

public void reflex(String str) {
  
  if("UserService".equals(str)){
   Class userClass= Class.forName("UserService");
   Constructor<?>[] constructors=userClass.getDeclaredConstructors();
   Constructor constructor=constructors[0];
   Object UserService=constructor.newInstance("333333","666666");
   System.out.println(UserService.toString());
  }
    
}

以java8為討論基礎,網上所說的反射只能通過無參構造方法創建對象是不正確的,事實證明,反射不僅僅可以通過有參構造方式創建對象,而且還可以通過私有構造方法創建對象,而且這種通過私有構造方法創建對象的方式會破壞單例模式,你想一下,單例模式中的構造方法之所以是私有就是為了不允許外部創建單例對象。而通過反射可以創建的話,那不是違背了單例模式的定理嗎。

例:只是為了說明反射,所有代碼中的單例只是一個簡單的餓漢式單例:

public class IdGenerator {
   private String k;
   private static final IdGenerator instance = new IdGenerator();

   private IdGenerator(String k) {
    this.k=k;
   }

   public static IdGenerator getInstance() {
    return instance;
   }
  }
    
public class reflex {

    public static void main(String[] args){
  
  Class idGeneratorClass= Class.forName("IdGenerator");
  Constructor<?>[] constructors=idGeneratorClass.getDeclaredConstructors();
  Constructor constructor=constructors[0];
    constructor.setAccessible(true);//暴力反射,可以突破私有權限
  Object idGenerator=constructor.newInstance("333333");
  System.out.println(idGenerator==IdGenerator.getInstance());
    
    }
}

這個例子既驗證了反射調用有參構造方法創建實例,又驗證了反射破壞單例模式。

反射會造成泛型擦除:

List<UserService> list=new ArrayList<UserService>();

  list.add(new UserService());
  list.add(new UserService());
  list.add(new UserService());

  Class<? extends List> listClass=list.getClass();
  Method method=listClass.getDeclaredMethod("add",Object.class);
  method.invoke(list,"123");

  for(int i=0;i<list.size();i++){
   System.out.println(list.get(i));
  }

上面的例子中通過反射創建的list對象,在調用add方法的時候不會限制類型,導致無法用某個類型去接收list集合中數據,否則會報類型轉換異常,這種情況只能直接返回前端。

效率問題 ,反射的效率比new字段創建對象的效率低很多,因此在使用的時候要特別注意性能問題,但是即便是這樣,我們寫出的代碼主要的性能影響點很少是反射造成,而大多情況是因為代碼結構框架,函數,工具,底層原理的不合理使用造成的。因此發射機制可以用在代碼中,但是要用在合適的位置。

現在來總結下反射的作用:

可以在程序運行過程中去操作字節碼文件和類對象進而進行得到類信息,創建對象以及執行對象方法等,不需要重新編譯,提高程序的擴展性 復用性 解耦

二、反射相關的四個類

反射相關的四個類,這些類的中的方法底層大多是native方法,所以反射其實是jvm底層實現。掌握了這四個類,靈活運用,基本就掌握了反射機制。

1.Class類

  • getClassLoader() 返回類加載器
  • getClasses() 返回一個數組,該數組中包含該類中所有公共類和接口類的類對象
  • getDeclaredClasses() 返回一個數組,數組中包含該類中所有類的和接口類的對象
  • forName(String className) 根據類名返回類的類對象
  • newInstance()創建類的實例
  • getPackage()獲取類的包
  • getSimpleName() 獲取類的名字
  • getSuperclass() 獲取當前類繼承的類的名字
  • getInterfaces() 獲取當前類實現的類或者接口
  • .class 獲取當前對象的類對象
  • getField(String str) 獲取public的字段對象 只能得到public
  • getFields() 獲取所有public字段對象 只能得到public
  • getDeclaredFild(String name) 取某個字段對象
  • getDeclaredFilds() 取所有字段對象
  • getAnnotation(Class) 獲取注解
  • getConstructor(String.calss...) 獲取該類中對應參數類型的構造方法
  • getConstructors()獲取該類的所有公有構造方法
  • getDeclaredConstructor(String.calss...)獲取該類中與參數類型匹配的構造方法
  • getDeclaredConstructors()獲取所有構造方法
  • getMethods()獲取該類所有公有方法
  • getMethod(String name,String.calss...) 獲取該類對應名稱和參數類型的公有方法
  • getDeclaredMethods() 獲取所有方法
  • getDeclaredMethods(String name,String.calss...)獲取該類對應名稱和參數類型的方法
  • isAnnotation()如果是注解類型返回true
  • isnotationPresent(注解類型)如果是指定類型的注解返回true
  • isArray()如果是數組類型返回true
  • isEnum()如果是枚舉類型 返回true
  • isInstance(Object obj)如果傳入的參數是該類的實例則返回true
  • isInterface()如果是接口類型返回true

2.Field類

field是類中的成員變量:變量和屬性是倆個概念,變量有get和set方法就是屬性。

  • get(Object obj)獲取obj對象中對應的屬性值
  • set(Object obj,Object val)設置obj對象中對應屬性值
  • setAccessible() 暴力反射,忽略訪問權限修飾符

3.Method類

  • invoke(Object obj,object args...) 入對象及參數調用該對象的該方法
  • getName() 取某個方法的名字
  • setAccessible() 暴力反射,忽略訪問權限修飾符

4.Constructor類

newInstance(object arg...) 傳入參數的時候,會調用有對應參數的構造方法創建對象,不傳參數就是使用默認構造方法。

setAccessible() 暴力反射,忽略訪問權限修飾符:


Class userClass= Class.forName("UserService");
Constructor<?>[] constructors=userClass.getDeclaredConstructors();
Constructor constructor=constructors[0];
Object UserService=constructor.newInstance("333333","666666"); 

所謂暴力反射,就是當類中有私有構造方法,私有屬性,私有方法的時候,對這些對象進行反射調用的時候會報錯,原因是無法突破私有權限,反射調用前先調用對象的setAccessible方法,設置為true,就可以突破私有權限,代碼可以看上面破壞單例的例子。

責任編輯:趙寧寧 來源: 碼農本農
相關推薦

2023-05-10 11:07:18

2022-07-26 00:00:22

HTAP系統數據庫

2014-04-17 16:42:03

DevOps

2022-01-17 07:32:34

Java參數方法

2021-01-15 07:44:21

SQL注入攻擊黑客

2021-11-09 09:48:13

Logging python模塊

2025-01-03 08:09:15

2021-11-26 08:07:16

MySQL SQL 語句數據庫

2014-11-28 10:31:07

Hybrid APP

2020-02-27 10:49:26

HTTPS網絡協議TCP

2019-09-16 08:40:42

2023-03-16 10:49:55

2015-07-31 10:35:18

實時計算

2023-10-24 08:53:24

FutureTas并發編程

2022-03-14 07:53:27

ELTETL大數據

2012-05-31 09:56:54

云安全

2022-12-12 08:46:11

2017-10-18 22:01:12

2019-11-06 09:52:01

JavaScript單線程非阻塞

2018-12-21 11:24:55

Java時間處理編程語言
點贊
收藏

51CTO技術棧公眾號

久久网站最新地址| 日本一区二区综合亚洲| 中国china体内裑精亚洲片| 成人网18免费网站在线| 国产亚洲一区在线| 国产成人在线亚洲欧美| 国产一区二区主播在线| 欧美日韩亚洲国产综合| 日本黄大片一区二区三区| 久久狠狠亚洲综合| 99理论电影网| 精品理论电影| 国内精品模特av私拍在线观看| 欧美6一10sex性hd| 欧美性猛交xxxx乱大交极品| 亚洲一级片网站| 国产毛片精品视频| 精品久久久三级| 91日韩视频| 国产成人亚洲综合青青| 欧美影院在线| 亚洲欧美另类自拍| 国产啊啊啊视频在线观看| 色婷婷亚洲婷婷| 在线国产小视频| 一区二区三区四区激情| 天天干天天综合| 国产午夜精品一区二区三区视频| 久久久久久久免费视频| 久久超级碰视频| 日本一区视频在线观看| 亚洲欧美日韩另类精品一区二区三区| 欧美日一区二区| 国产精品久久久久一区二区| 中文在线免费视频| 精品国产91久久久久久久妲己 | 一广人看www在线观看免费视频| 亚洲免费av网站| 天天激情综合| 亚洲三级电影网站| jizzjizz中文| 亚洲曰韩产成在线| 亚洲国产经典视频| 国产日产欧美视频| 欧美日韩亚洲第一| 99麻豆久久久国产精品免费| 300部国产真实乱| 黄色美女网站在线观看| 日本乱人伦一区| 精品美女视频在线观看免费软件| 国产日产久久高清欧美一区| 精品久久久网| 欧美成人性生活| 国产精品网站在线看| 国产成人欧美日韩在线电影| 亚洲精品少妇久久久久久| 国产精品五月天| 在线观看国产中文字幕| 日韩国产在线不卡视频| 亚洲中文字幕无码专区| 国产亚洲va综合人人澡精品| 国产精品久线观看视频| 日韩av免费看| 久久精品高清| 91免费在线视频| 亚洲日本久久| 久久久久久久久网| 国产色91在线| 一级片在线播放| 欧美精品久久99| 性欧美1819sex性高清| 欧美黄色免费网站| 999精品视频| 亚洲乱码一区二区三区三上悠亚| 成年人国产精品| 在线播放evaelfie极品| 欧美日本国产视频| 日韩电影精品| 国产自摸综合网| 久久久久国产精品一区三寸| 麻豆映画在线观看| 亚洲丝袜自拍清纯另类| 成年人在线观看| 日韩最新av在线| 91影院成人| 国产乱子伦精品视频| 亚洲精品v日韩精品| 国产激情在线| 韩国福利视频一区| 久久成人一区| 国产福利一区视频| 欧美三级电影网站| 国产精品视频首页| 国产一级二级三级精品| 久久久国产精品不卡| 午夜视频在线免费观看| 久久久成人精品视频| 国产综合久久| 国产精品入口免费软件| 7777精品伊人久久久大香线蕉完整版 | 日韩在线成人| 狠狠综合久久av| 久久久久久久久久看片| 色哟哟免费在线观看| 欧美激情在线有限公司| 三级一区在线视频先锋| 福利电影导航| 日韩www在线| 最新国产精品| 污视频网站观看| 亚洲福利视频在线| 久久久人成影片免费观看| 国产日产欧美视频| 亚洲激情免费观看| 国内精品久久久久久久97牛牛| 青青草原av在线播放| 精品久久久久av影院| 久久一级电影| 一区二区三区视频在线观看免费| 精品国内二区三区| 国产高清欧美| 9久久婷婷国产综合精品性色| 亚洲精品v欧美精品v日韩精品| 四虎8848精品成人免费网站| 超碰97人人射妻| 国产一区二区三区在线播放免费观看| 国产欧美日韩综合一区在线播放 | 在线精品视频小说1| 极品一区美女高清| 日本福利视频在线观看| 欧美日韩另类一区| 成人情趣视频网站| 一区二区三区视频网| 色偷偷av一区二区三区| 久草这里只有精品视频| 麻豆tv入口在线看| 成人xxxxx色| 午夜久久久久久电影| 欧美久久香蕉| 国产成人无码一二三区视频| 亚洲欧美色婷婷| 美腿丝袜亚洲综合| 欧美日韩激情美女| 五月亚洲婷婷| 欧美亚洲日本一区二区三区| 日韩精品极品在线观看| 日韩1区2区3区| 日本网站在线免费观看视频| 成人黄色大片在线免费观看| 亚洲在线视频一区| 久久93精品国产91久久综合| 国产一级不卡毛片| 国产欧美69| 亚洲一区亚洲二区| 欧美日韩性视频在线| 99热国内精品永久免费观看| 麻豆影视在线观看| 成人精品久久一区二区三区| 午夜视频在线观看一区二区三区 | 日韩欧美久久久| 日韩午夜免费| 成人福利在线观看视频| 国产一区国产精品| 欧美精三区欧美精三区| 午夜在线一区| 99在线视频影院| 免费看日本黄色| 欧美成人免费一级人片100| 国产欧美一区二区三区沐欲| 欧美挤奶吃奶水xxxxx| 激情婷婷丁香| 51精品国产人成在线观看| 在线亚洲人成电影网站色www| 在线欧美福利| 国产777精品精品热热热一区二区| 天天爱天天做天天操| 日韩中文字幕在线观看| 日本一区二区动态图| 成人看的视频| 四虎久久免费| 中国人体摄影一区二区三区| www.欧美三级电影.com| 中文字幕一区二区三区不卡| 综合一区二区三区| 久久男人av资源站| 亚洲国产成人va在线观看麻豆| 国产极品jizzhd欧美| 欧美三级日韩三级国产三级| 九九国产精品视频| 色播一区二区| 99青草视频在线播放视| 日本五级黄色片| 国产mv久久久| 91精品国产综合久久精品性色| 风间由美一区二区三区在线观看| 国产一区二区三区不卡av| 国产高清在线看| 欧美久久久久久久久久久久久| 国产精品女人网站| 亚洲美女黄色片|