Java程式設計:一步步教你如何深入瞭解神秘的Java反射機制

Java大蝸牛發表於2018-08-09

Java程式設計:一步步教你如何深入瞭解神秘的Java反射機制


在進入正文之前,順便給大家推薦一個Java架構方面的交流學習群: 725633148 ,裡面會分享一些資深架構師錄製的影片錄影:有Spring,MyBatis,Netty原始碼分析,高併發、高效能、分散式、微服務架構的原理,JVM效能最佳化這些成為架構師必備的知識體系。相信對於已經工作和遇到技術瓶頸的同學,在這個群裡會有你需要的內容。有需要的同學請抓緊時間加入進來。

定義:Java語言中 一種 動態(執行時) 訪問、檢測 & 修改它本身的能力

作用:動態(執行時)獲取 類的完整結構資訊 & 呼叫物件的方法

類的結構資訊包括:變數、方法等

正常情況下,Java類在編譯前,就已經被載入到JVM中;而反射機制使得程式執行時還可以動態地去操作類的變數、方法等資訊

2.1 優點

靈活性高。因為 反射屬於動態編譯 ,即只有到執行時才動態建立 &獲取物件例項。

編譯方式說明:

1. 靜態編譯:在編譯時確定型別 & 繫結物件。如常見的使用new關鍵字建立物件

2. 動態編譯:執行時確定型別 & 繫結物件。動態編譯體現了Java的靈活性、多型特性 & 降低類之間的藕合性

2.2 缺點

執行效率低

因為反射的操作 主要透過JVM執行,所以時間成本會 高於 直接執行相同操作

因為介面的通用性,Java的invoke方法是傳object和object[]陣列的。基本型別引數需要裝箱和拆箱,產生大量額外的物件和記憶體開銷,頻繁促發GC。

編譯器難以對動態呼叫的程式碼提前做最佳化,比如方法內聯。

反射需要按名檢索類和方法,有一定的時間開銷。

容易破壞類結構

因為反射操作饒過了原始碼,容易干擾類原有的內部邏輯

動態獲取 類檔案結構資訊(如變數、方法等) & 呼叫物件的方法

常用的需求場景有:動態代理、工廠模式最佳化、Java JDBC資料庫操作等

下文會用實際例子詳細講解

4.1 Java反射機制提供的功能

Java程式設計:一步步教你如何深入瞭解神秘的Java反射機制


4.2 實現手段

反射機制的實現 主要透過 操作java.lang.Class類

下面將主要講解 java.lang.Class 類

4.2.1 java.lang.Class 類

定義:java.lang.Class類是反射機制的基礎

作用:存放著對應型別物件的 執行時資訊

Java程式設計:一步步教你如何深入瞭解神秘的Java反射機制


每種型別的Class物件只有1個 = 地址只有1個

Java程式設計:一步步教你如何深入瞭解神秘的Java反射機制


Java反射機制的實現除了依靠Java.lang.Class類,還需要依靠:Constructor類、Field類、Method類,分別作用於類的各個組成部分:

Java程式設計:一步步教你如何深入瞭解神秘的Java反射機制


4.3 使用步驟

在使用Java反射機制時,主要步驟包括:

1. 獲取 目標型別的Class物件

2. 透過 Class 物件分別獲取Constructor類物件、Method類物件 & Field 類物件

3. 透過 Constructor類物件、Method類物件 & Field類物件分別獲取類的建構函式、方法&屬性的具體資訊,並進行後續操作

下面,我將詳細講解每個步驟中的使用方法。

步驟1:獲取 目標型別的Class物件

Java程式設計:一步步教你如何深入瞭解神秘的Java反射機制


此處額外講一下java.lang.reflect.Type類

java.lang.reflect.Type是 Java中所有型別的父介面

這些型別包括:

Java程式設計:一步步教你如何深入瞭解神秘的Java反射機制


之間的關係如下

Java程式設計:一步步教你如何深入瞭解神秘的Java反射機制


步驟2:透過 Class 物件分別獲取Constructor類物件、Method類物件 & Field 類物件

Java程式設計:一步步教你如何深入瞭解神秘的Java反射機制


Java程式設計:一步步教你如何深入瞭解神秘的Java反射機制


步驟3:透過 Constructor類物件、Method類物件 & Field類物件分別獲取類的建構函式、方法 & 屬性的具體資訊 & 進行操作

Java程式設計:一步步教你如何深入瞭解神秘的Java反射機制


至此,關於Java反射機制的步驟說明已經講解完畢。

4.4 特別注意:訪問許可權問題

背景

反射機制的預設行為受限於Java的訪問控制

如,無法訪問( private )私有的方法、欄位

衝突

Java安全機制只允許檢視任意物件有哪些域,而不允許讀它們的值

若強制讀取,將丟擲異常

解決方案

脫離Java程式中安全管理器的控制、遮蔽Java語言的訪問檢查,從而脫離訪問控制

具體實現手段:使用Field類、Method類 & Constructor類物件的setAccessible()

Java程式設計:一步步教你如何深入瞭解神秘的Java反射機制


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31545684/viewspace-2199596/,如需轉載,請註明出處,否則將追究法律責任。

相關文章