學Java反射,看這篇就夠了 | 原力計劃

2021-01-17 程序人生

作者 | P6級程式設計師

責編 | 王曉曼

出品 | CSDN博客

首先學習反射之前,我要提出疑問:

反射是個什麼東西?它是用來做什麼的?平時的應用場景有哪些?為啥要用它?它有什麼優缺點?它的工作原理是什麼?我怎麼使用它?

這麼多的問題,這是在挑釁啊,既然如此,那麼我想起來宮本的那句:想挑戰的,一個一個來。先解決第一個問題。

 

此為何物

 

百度看了看反射的介紹:

超過二秒後,我表示看不下去了,就不能簡單點嗎?這是給人看的嗎?像我這種人,是看不下去的。

我們來一句話定義反射:

反射就是把 Java 類中的各種成分映射成一個個的 Java 對象。

不理解這句話什麼意思?沒關係,在我百度了幾分鐘後,找到三種解釋:

解釋一:一個類有:成員變量、方法、構造方法、包等等信息,利用反射技術可以對一個類進行解剖,把各個組成部分映射成一個個對象。

解釋二:說反射先聊聊正射。

反射機制是不知道類是什麼樣的,它是根據類的類名,去獲取一個實例,然後根據方法名去執行方法。好比說,一般情況下畫一隻老虎,問我得先知道老虎長什麼樣子才能畫出來;有了反射機制,我只要知道「老虎」這個名字就能畫出來。

解釋三:假如我們有兩個程式設計師,一個程式設計師在寫程序的時候,需要使用第二個程式設計師所寫的類,但第二個程式設計師並沒完成他所寫的類。那麼第一個程式設計師的代碼能否通過編譯呢?這是不能通過編譯的。利用Java反射的機制,就可以讓第一個程式設計師在沒有得到第二個程式設計師所寫的類的時候,來完成自身代碼的編譯。

解釋四:如果你是方法,快遞員是虛擬機。快遞員通過地址查地圖找你的叫反射調用。直接去找你的叫直接調用。

現在我們基本已經了解什麼是反射了,接著需要將第二個問題搞定。

 

該物用途

 

接著百度:

 用途太多,概念也很多,我需要一句話就可以解釋它的作用或者用途:

反射可以賦予jvm動態編譯的能力。

看到又出現一個詞,動態編譯,來我們來嘮嘮這個詞。

Java中編譯類型有兩種:

如果不理解,那麼給個業務場景幫助你理解:比如開發一個閱讀器,支持txt,pdf,doc三種格式。我們把讀txt,讀pdf,讀doc定義為三個功能模塊。

顯然,動態編譯1速度快,2節省了系統資源,3利於今後拓展。

那麼這個JVM動態編譯常用的場景有哪些呢?或者說反射的使用場景(用途)有哪些?此物的用途?

場景一:在日常的第三方應用開發過程中,經常會遇到某個類的某個成員變量、方法或是屬性是私有的或是只對系統應用開放,這時候就可以利用Java的反射機制通過反射來獲取所需的私有成員或是方法。

場景二:當我們在使用IDE(如Eclipse,IDEA)時,當我們輸入一個對象或類並想調用它的屬性或方法時,一按點號,編譯器就會自動列出它的屬性或方法,這裡就會用到反射。

場景三:反射最重要的用途就是開發各種通用框架。很多框架(比如Spring)都是配置化的(比如通過XML文件配置JavaBean,Action之類的),為了保證框架的通用性,它們可能需要根據配置文件加載不同的對象或類,調用不同的方法。

為啥要用它?它有什麼優缺點?

 

Java的反射機制就是增加程序的靈活性,解耦。反射就是一種機制,可以讓你僅知道類的名字的情況下,可以了解整個類的內部的結構,並且訪問內部的成員和方法等。

解釋:對於大型的軟體,一個大公司的各個小組都有自己的分工,去實現不同的模塊,那麼各個小組之間如何協作就非常關鍵。例如A小組完成IPolicy接口的實現,而B小組需要使用A的實現,這時候就可以使用反射機制,B小組完全不用知道IPolicy是如何實現的,只需要知道實現後的類名即可,或者說,類名完全保存在一個xml或者屬性中,由A小組去填充,這樣B小組的代碼看上去就和A毫無瓜葛。

因此反射在一般框架中使用較多。因為框架要適用更多的情況。對靈活性要求較高。

優勢:

缺點:

相較直接調用在量大的情景下反射性能下降。

存在一些內部暴露和安全隱患。

針對它的缺點,我們聊聊反射到底慢在哪些地方

反射的工作原理?反射技術的組成部分?

 

萬物皆對象,我們定義的類其實從面向對象的角度來分析,它其實也是一個具體的對象,它是一個描述類的實例。描述這個類中有哪些屬性,行為等等內容.。我們可以通過定義類,來描述一組具有相同屬性,行為的實例對象。比如我們創建Person 類。

Class Person {
    String ID;
    int age;Seven
    void talk(){

    }
}

我們可以基於這個類創建具體不同身份證號和姓名的 Person 實例(new Person)。每一個實例都具有身份證號,年齡,說話的行為。通過上面的簡單案例,我們可以這麼理解在Java 語言中Class 的定義,是創建對象的統一模板。

那麼我們可以思考這樣一個問題,既然不管是 Java 語言默認的類還是我們自定義創建的類都 是為了創建具有相同行為屬性的對象的模板。

那麼每一個類我們在定義的時候,是不是也可以抽取共性的東西,比如,每一個類都有包名,屬性定義,行為(方法),構造器等等。

那麼既然每一個類都會具備這樣的內容,那麼這些類對象實例,應該也可以抽取成一個公有的模板,用於創建類對象實例的模板。所以在java 中,這個類定義的創建模板就是我們 java 語言中的 java.lang.Class 類。在 Class 的模板中,我們也可以找到大家耳熟能詳的模板類如Method,Constructor,Field...

深入 Class 內部

通過上面的內容,我們已經了解到我們創建的每一個自定義的Class實例都是基於他的模板類java.lang.Class 類。在大家每一個編寫的類實例中,都會定義這個類的包名,類名,訪問域,特徵符,構造器,欄位,函數,父類,接口等等內容。這些內容在我們的 Class 類中都提供了對應的獲取方法進行獲取。


如何使用?

 

1、反射-基本信息操作

intmodifier = clazz.getModifiers(); //獲取類的修飾符

Packagepackage= clazz.getPackage();//獲取類的包名

StringfullClassName = clazz.getName();//獲取類的全路徑名稱

StringsimpleClassName = clazz.getSimpleName();//獲取類的簡單名稱

ClassLoaderclassLoader = clazz.getClassLoader();//獲取類的類加載器

Class[]interfacesClasses = clazz.getInterfaces();//獲取類實現的接口列表

Classfc= clazz.getSuperclass();//獲取類的父類

Annotation[]annotations= clazz.getAnnotations(); //獲取類的註解列表

2、反射-欄位操作

Field[]fields = clazz.getFields();//獲取類中所有的公有欄位包含繼承

Field[]declaredFields=clazz.getDeclaredFields();//獲取類中定義的欄位 內部

FieldnameField=clazz.getField("name");//獲取指定名稱的公有欄位

FieldlikeDescField=clazz.getDeclaredField("likeDesc");//獲取指定名稱類中定義的欄位

intmodifersFiled = likeDescField.getModifiers();//獲取欄位的修飾

nameField.setAccessible(true);//指定欄位強制訪問

nameField.set(person,"小皮皮");//成員欄位賦值(需指定對象)

descriptionField.set(null,"沒有結婚的都是男孩!");//靜態欄位賦值

3、反射-方法操作

Method[]methods = clazz.getMethods();//獲取類中所有的公有方法繼承

Method[]declaredMethods = clazz.getDeclaredMethods();//獲取類中定義的方法

MethodtalkMethod = clazz.getMethod("talk", String.class);//獲取類中指定名稱和參數的公有方法

MethodpugMethod = clazz.getDeclaredMethod("pickUpGirls") //獲取類中定義指定名稱和參數的方法

intmodifers = pugMethod .getModifiers();//獲取方法的修飾符

talkMethod.invoke(boy,"ILOVE SEVEN");//指定對象進行成員方法的調用

pugMethod.setAccessible(true);//指定方法的強制訪問

pickUpGirlsMethod.invoke(null);//靜態方法的調用

4、反射-構造器操作

Constructor[]cons = clazz.getConstructors();//獲取類中所有的公有構造器

Constructor[]cons = clazz.getDeclaredConstructors();//獲取類中所有的構造器

ConstructorconNoParam= clazz.getDeclaredConstructor();//獲取類中無參的構造器

Constructorcon= clazz.getDeclaredConstructor(String.class,String.class); //獲取類中有參構造

intmodifers = con.getModifiers();//獲取構造器的修飾符

conNoParam.newInstance();//構造器實例對象

con.setAccessible(true);//指定方法的強制訪問

con.newInstance('abc','def');//有參構造調用

class.newInstacne();//class直接調用默認無參構造

舉一反三

 

疑問一:現在我們基本解決上面提出的幾個問題了,有了一個基本的了解之後,有沒有想起我們常常被面試的時候,問到的Spring框架IOC控制反轉,是不是跟反射有那麼一些關聯?或者說SpringIOC容器它是怎麼做到控制反轉的?

疑問二:僅知道類的名字的情況下,可以了解整個類的內部的結構,並且訪問內部的成員和方法等。那麼針對私有的一些方法,或者構造器,豈不是可以破壞它,比如說:通過反射機制可以破壞單例模式,它為啥可以做到這一點的?通過反射機制可以破壞單例模式

版權聲明:本文為CSDN博主「P6級程式設計師」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/java_programmer_liao/article/details/106013181

6月2日20:00,CSDN 創始人&董事長、極客幫創投創始合伙人蔣濤攜手全球頂級開源基金會主席、董事,聚焦中國開源現狀,直面開發者在開源技術、商業上的難題,你絕不可錯過的開源巔峰對談!立即免費圍觀

更多精彩推薦

☞大佬 Zed 玩轉跨界:不會繪畫的音樂家不是好程式設計師

☞航拍高手、吉他十級,6500+Star 開源項目作者,後浪程式設計師給力!

☞面試官:你的 SQL 一般有幾個 join?| 原力計劃

☞基於深度學習和傳統算法的人體姿態估計,技術細節都講清楚了

☞面試中遇到這 3 個SQL問題,最容易掉坑裡!

☞好撲科技結合區塊鏈行業發展趨勢,重磅推出「好撲區塊鏈合伙人」計劃

點擊閱讀原文,精彩繼續。

相關焦點

  • Java反射是什麼?看這篇絕對會了!
    反射是開源框架中的一個重要設計理念,在源碼分析中少不了它的身影,所以,今天我會儘量用淺顯易懂的語言,讓你去理解下面這幾點:(1)反射的思想以及它的作用: 概念篇(2)反射的基本使用及應用場景: 應用篇(3)使用反射能給我們編碼時帶來的優勢以及存在的缺陷: 分析篇反射的思想及作用有反必有正,就像世間的陰和陽,計算機的0和1一樣。
  • Java反射機制深入詳解
    一.概念反射就是把Java的各種成分映射成相應的Java類。Class類的構造方法是private,由JVM創建。反射是java語言的一個特性,它允程序在運行時(注意不是編譯的時候)來進行自我檢查並且對內部的成員進行操作。例如它允許一個java的類獲取他所有的成員變量和方法並且顯示出來。
  • Java基礎教程:java反射機制教程
    請看下面的代碼: 這是一個最簡單不過的類,當我們使用的時候直接new出來一個User對象即可。這時候java語言在設計的時候為我們提供了一個機制,就是反射機制,他能夠很方便的去解決我們的問題。
  • Java反射初探 ——「當類也學會照鏡子」
    動態加載類 我理解的「反射」的意義(僅個人理解哈) 我理解的java反射機制就是: 提供一套完善而強大的API「反射「類的結構。因為不照鏡子看不清楚自己的全貌,「鏡子」就是為了解決這個問題出現的(為我們提供全面分析類的能力)  好吧,我知道這聽起來還是很模糊,讓我們一步一步來:類也是對象在java裡有一句話:萬物皆對象, 即使是int
  • 如何使用JAVA反射/JAVA反射實例
    JAVA反射技術,在平時我們的開發中雖然很少會用到例如讀取配製文件可能就用到這個技術,但在我們所使用的框架源碼中是經常會用到的。getName())  ; // 得到類的名稱  System.out.println("類名稱:" + c3.getName())  ; // 得到類的名稱 }};2、反射如何操作對象
  • Java 反射最佳實踐
    聽到這句話後我就知道,今天一定不好過了,奇葩需求又來了。二、分析當我們接到上面需求後,我長舒一口氣,因為這回的需求還比較簡單。我相信有人會說:「反射就那幾個api,一直沒變過,你就不會自己去查啊,覺得麻煩就別寫代碼啊,不知道反射的內部細節你怎麼去提高呢?」
  • Java面試高頻考點:反射機制使用大全
    作為一個Java開發工程師,在面試的過程中,反射機制也是經常會被問到的一個問題。例如Spring的IOC實現機制,其底層都是依賴於java的反射機制,因此,這是一個非常重要的知識點。對於初學java的同學來說,掌握其使用方法很有必要。
  • Java 反射:框架設計的靈魂
    在學習 Java 反射之前,先讓我們看看這幾個概念。,就是 Java 反射機制。不過很多場景中,在代碼運行之前並不知道需要使用哪個類,或者說在運行的時候才決定使用哪個類;比如有這麼一個功能:「調用阿里雲的人臉識別 API 」;這還不簡單,參考對方的 API 文檔,很快就能實現。
  • 反射——Java高級開發必須懂得
    描述:在 main 函數中,有一個 String args[] 參數,這就表示在執行某 .class 文件時,可以對 main 函數傳字符串參數(例如:命令行中:java OfficeBetter Excel,傳給主函數的參數就是Excel,如果傳多個參數,參數用空格隔開),Office類中使用了兩個類(沒有提供這兩個類),並調用其相應的方法
  • 簡析:Java反射、Java反射定義、反射的基石
    Java反射定義在程序運行過程中,對於任意一個類,可以獲得該類的屬性和方法;對於任意一個對象,可以調用該對象的任意一個屬性和方法。在運行時動態獲取類的信息和動態調用對象的屬性和方法稱為Java反射機制。
  • 原力計劃第2張合輯上線 唱出荒誕世界的獨立主張
    4月29日,「原力計劃2019」第二張「原力合輯」《局部硬核》正式上線,九組個性鮮明的優質音樂人帶來了九首充滿個人主張的硬核之作,要向荒誕世界唱出屬於自己內心的聲音。這也是繼3月29日推出首張「原力合輯」《地心遊記》後,為原創樂迷帶來的第二波重磅驚喜。「原力合輯」第二輯硬核首發 拒絕平庸個性十足繼首張「原力合輯」《地心遊記》發表以來,十首生動表達音樂人真實生活感受的鮮活原創佳作,受到了業內人士及原創樂迷的關注。
  • 什麼是JAVA反射機制,詳細解讀JAVA面試的核心技術
    一、什麼叫Java反射機制?Java中的反射機制是指在運行狀態中,對於任意一個類,能夠動態獲取這個類中的屬性和方法;對於任意一個對象,都能夠任意調用它的屬性和方法。這種動態獲取類的信息以及動態調用對象方法的功能稱為Java的反射機制。
  • 「JAVA」萬字長篇詳述字節碼對象與反射機制完成動態編程
    Java 反射在Java的開發環境中,運行java文件需要使用:java xx.java 命令,運行java命令後,反射提供一組api,通過調用api,便能獲取運行時的類信息;Java 中通過java.lang.reflect類庫來支持反射;03
  • Java反射到底慢在哪?
    反射具體是怎麼影響性能的?這引起了我的反思。是啊,在闡述某個觀點時確實有必要說明原因,並且證明這個觀點是對的,雖然反射影響性能人盡皆知,我曾經也真的研究過反射是否存在性能問題,但並沒有在寫文章的時候詳細說明。
  • 適合Java新手的開源項目集合——在 GitHub 學編程
    這裡是 HelloGitHub 的《GitHub 上適合新手的開源項目》系列,共計 5 篇文章:C++ 篇Python 篇Go 篇Java 篇>JavaScript 篇本期是 Java 篇 希望這篇文章能讓大家找到 GitHub 上適合自己學習的 Java 開源項目。
  • 開發崗位這麼多,為什麼選Java?你學Java了嗎-開課吧
    提到C++語言,很多人發現在使用過程中最容易出現的錯誤就是內存管理,而java有自動垃圾回收器,不用擔心內存。市場需求決定你的學習方向,招聘平臺上招程式設計師java佔比很高。java難學嗎?學java要學多久-開課吧
  • 騰訊音樂人2020原力計劃巡演燃動深圳
    隨著騰訊音樂人2020原力計劃巡演特別場深圳站於11月21日圓滿落下帷幕,記者今日從騰訊獲悉,原力計劃全國巡演接下來將在重慶、長沙、成都、西安、天津、石家莊,為樂迷朋友解鎖更多原創音樂的新玩法,帶去更多溫暖力量。目前,騰訊音樂人2020原力計劃巡演已走過南京,杭州,深圳三座城市。
  • 你知道java反射機制中class.forName和classloader的區別嗎?
    一、類加載機制上面兩種加載類的方式說到底還是為了加載一個java類,因此需要先對類加載的過程進行一個簡單的了解。我們寫好的程序,然後run運行,過程可以直接看下面這張圖:往細了看大致分為5個階段:(1)加載:java類運行時候會生成一個class字節碼文件,加載的過程就是去我們的作業系統尋找這個class文件。(2)連結:這個過程就是把class文件加載到java虛擬機。
  • 原力計劃全國巡演深圳站 喚醒原創音樂多元之「形」
    繼長沙首站之後,9月22日,騰訊音樂人·原力計劃「不凡現場」全國巡演第二站登陸深圳HOULIVE,六組來自原力20強的音樂新人登上舞臺,從文氣民謠、青春朋克唱到酷炫嘻哈、純正布魯斯,為現場觀眾呈現了多元風格的精彩演出,也開啟了「原力計劃」第二維「形」之覺醒,在滿場掌聲和歡呼中,讓人見證了新鮮的音樂
  • PDMS-2反射訓練:蘭朵反應|【一起學運動訓練】
    PDMS-2反射訓練:蘭朵反應|【一起學運動訓練】 今天給大家介紹的是反射訓練中的第三個:蘭朵反應。