反射原來是這麼玩的(反射一開,誰都不愛)

2021-01-07 java之旅

反射的發展歷史

1996年01月23日,jdk 1.0版本發布,代號為Oak(橡樹)。

這個代號為Oak(橡樹)的版本,在發布後的第二年,1997年02月19日,發布jdk 1.1版本,這次版本發布中引入了**反射**機制。

通俗的解釋就是:無論是公有還是私有的方法、屬性、構造方法,全都可以用反射進行獲取、進行賦值、調用。聽到這個解釋,是不是感覺反射很強。

正因為反射的強大,在java世界裡運用的地方有很多,比如:Java類加載和初始化、Java中RTTI、Spring的IOC,。

如此廣泛的運用,只能說反射除了強,用起來肯定很爽。我想起我的同事,IT界的刁民,總是熱衷於反射。

他在講解他是如何運用反射時,嘴角總是壓抑不住的微笑,這種迷戀反射的樣子,像極了愛情。

正所謂:反射一開,誰都不愛。(傲嬌)

下面就看看反射究竟是如何在程序中使用的。

反射的概述和使用

反射的概述

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

反射的使用

這裡使用一個Animal類來作為示範,可以看到這個類裡的成員變量、方法、構造方法的訪問修飾符既有public、也有privat的 。下面就將使用反射獲取不同修飾符修飾的成員變量、方法、構造方法。

package com.shuai.ioc.ref;public class Animal { /** * 動物名字 */ public String name; /** * 動物年齡 */ protected int age; @Override public String toString() { return "Animal{" + "name='" + name + '\'' + ", age=" + age + '}'; } /** * 默認的構造方法 * * @param name */ Animal(String name) { System.out.println("執行了" + "默認的構造方法 " + name); } /** * 無參構造方法 */ public Animal() { System.out.println("執行了" + "無參構造方法 "); } /** * 有一個參數的構造方法 * * @param name */ public Animal(char name) { System.out.println("執行了" + "有一個參數的構造方法 name:" + name); } /** * 有多個參數的構造方法 * * @param name * @param age */ public Animal(String name, int age) { System.out.println("執行了" + "有多個參數的構造方法 name:" + name + "age:" + age); } /** * protected的構造方法 * * @param n */ protected Animal(boolean n) { System.out.println("執行了" + "受保護的構造方法 n:" + n); } /** * 私有構造方法 * * @param age */ private Animal(int age) { System.out.println("執行了" + "私有構造方法 age:" + age); this.name = "私有構造方法調用成功"; this.age = age; } /** * 公有方法 * * @param s */ public void public1(String s) { System.out.println("調用了" + "公有的方法" + ": public1 , s:" + s); } /** * protected的方法 */ protected void protected2() { System.out.println("調用了" + "protected的方法" + ": protected2 "); } /** * 友好的方法 */ void friendly1() { System.out.println("調用了" + "友好的方法" + ": friendly1 "); } /** * 私有方法 * * @param age * @return */ private String private1(int age) { System.out.println("調用了" + "私有方法" + ": private1 ,age:" + age); return age + ""; }}用反射獲取類的構造方法

在Class類中,提供一系列獲取被反射類構造方法的方法。

批量獲取構造方法的方法public Constructor[] getConstructors():所有」公有的」構造方法public Constructor[] getDeclaredConstructors():獲取所有的構造方法(包括私有、受保護、默認、公有)獲取單個的方法,並調用public Constructor getConstructor(Class... parameterTypes):獲取單個的」公有的」構造方法public Constructor getDeclaredConstructor(Class... parameterTypes):獲取」某個構造方法」可以是私有的,或受保護、默認、公有;調用構造方法newInstance(Object… initargs)package com.shuai.ioc.ref;import com.shuai.ioc.Book;import java.lang.reflect.Constructor;public class ConstructorsTest {public static void main(String[] args) throws Exception { //1.加載Class對象 Class clazz = Class.forName("com.shuai.ioc.ref.Animal"); //2.獲取所有公有構造方法 System.out.println("所有公有構造方法"); Constructor[] conArray = clazz.getConstructors(); for (Constructor c : conArray) { System.out.println(c); } // 所有的構造方法,公有、私有都行 System.out.println(""); System.out.println("所有的構造方法,包括:私有、受保護、默認、公有"); conArray = clazz.getDeclaredConstructors(); for (Constructor c : conArray) { System.out.println(c); } // 獲取公有、無參的構造方法 System.out.println(""); System.out.println("獲取公有、無參的構造方法"); Constructor con = clazz.getConstructor(null); System.out.println("con = " + con); //調用構造方法 Object obj = con.newInstance(); // 獲取私有構造方法 System.out.println(""); System.out.println("獲取私有構造方法,並調用"); con = clazz.getDeclaredConstructor(int.class); System.out.println(con); //暴力訪問,忽略掉訪問修飾符 con.setAccessible(true); //調用構造方法 Animal animal = (Animal) con.newInstance(1); System.out.println(animal.toString());}}用反射獲取類的方法

在Class類中,提供一系列獲取被反射類構造方法的方法。

批量的public Method[] getMethods():獲取所有」公有方法」;(包含了父類的方法也包含Object類)public Method[] getDeclaredMethods():獲取所有的成員方法,包括私有的(不包括繼承的)獲取單個的public Method getMethod(String name,Class<?>... parameterTypes),name: 方法名;Class ...:形參的Class類型對象public Method getDeclaredMethod(String name,Class<?>... parameterTypes),obj:要調用方法的對象;args:調用方式時所傳遞的實參;調用方法public Object invoke(Object obj,Object... args),obj:要調用方法的對象;args:調用方式時所傳遞的實參;package com.shuai.ioc.ref;import java.lang.reflect.Method;public class MethodClassTest {public static void main(String[] args) throws Exception { //1.獲取Class對象 Class stuClass = Class.forName("com.shuai.ioc.ref.Animal"); //2.獲取所有公有方法 System.out.println("獲取所有 公有 方法"); stuClass.getMethods(); Method[] methodArray = stuClass.getMethods(); for (Method m : methodArray) { System.out.println(m); } System.out.println(); System.out.println("獲取所有的方法,包括私有的"); methodArray = stuClass.getDeclaredMethods(); for (Method m : methodArray) { System.out.println(m); } System.out.println(); System.out.println("獲取公有的public1()方法"); Method m = stuClass.getMethod("public1", String.class); System.out.println(m); //實例化一個Student對象 Object obj = stuClass.getConstructor().newInstance(); m.invoke(obj, "this is name value"); System.out.println(); System.out.println("獲取私有的private1()方法"); m = stuClass.getDeclaredMethod("private1", int.class); System.out.println(m); m.setAccessible(true);//解除私有限定 Object result = m.invoke(obj, 20);//需要兩個參數,一個是要調用的對象(獲取有反射),一個是實參 System.out.println("返回值:" + result);}}用反射獲取類的欄位

在Class類中,提供一系列獲取被反射類構造方法的方法。

批量的Field[] getFields():獲取所有的」公有欄位」Field[] getDeclaredFields():獲取所有欄位,包括:私有、受保護、默認、公有;獲取單個的public Field getField(String fieldName):獲取某個」公有的」欄位;public Field getDeclaredField(String fieldName):獲取某個欄位(可以是私有的)設置欄位的值public void set(Object obj,Object value):obj:要設置的欄位所在的對象;value:要為欄位設置的值;package com.shuai.ioc.ref;import java.lang.reflect.Field;public class FieldsTest {public static void main(String[] args) throws Exception { //1.獲取Class對象 Class animalClass = Class.forName("com.shuai.ioc.ref.Animal"); //2.獲取欄位 System.out.println("獲取所有公有的欄位"); Field[] fieldArray = animalClass.getFields(); for (Field f : fieldArray) { System.out.println(f); } System.out.println(); System.out.println("獲取所有的欄位(包括私有、受保護、默認的)"); fieldArray = animalClass.getDeclaredFields(); for (Field f : fieldArray) { System.out.println(f); } System.out.println(); System.out.println("獲取公有欄位並調用"); Field f = animalClass.getField("name"); System.out.println(f); //獲取一個對象 Object obj = animalClass.getConstructor().newInstance();//產生Student對象--》Student stu = new Student(); //為欄位設置值 f.set(obj, "dog");//為Student對象中的name屬性賦值--》stu.name = "劉德華" //驗證 Animal stu = (Animal) obj; System.out.println("驗證name:" + stu.name); System.out.println(); System.out.println("獲取私有欄位並調用"); f = animalClass.getDeclaredField("name"); System.out.println(f); f.setAccessible(true);//暴力反射,解除私有限定 f.set(obj, "this is name value"); System.out.println("驗證name:" + stu);}}反射越過泛型檢查

編寫代碼時,如果我們設置容器list為String類型,在調用add方法插入數據時入參傳了其他類型,編譯時會無法成功,但是通過反射卻可以執行,實例代碼:

package com.shuai.ioc.ref;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.List;/* * 通過反射越過泛型檢查 * */public class IgnoreType { public static void main(String[] args) throws Exception { List<String> list = new ArrayList<>(); list.add("one"); //反射獲取list對象 Class listClass = list.getClass(); // 調用list對象的add方法 Method m = listClass.getMethod("add", Object.class); m.invoke(list, 100); //輸出驗證 for (Object obj : list) { System.out.println(obj); } }}

相關焦點

  • 《和平精英》地宮稜鏡反射圖文攻略 地宮稜鏡反射怎麼玩
    導 讀 在和平精英裡,地宮稜鏡反射是需要調整稜鏡的酵素,才能通關,具體怎麼玩呢?下面就為大家帶來詳細的攻略介紹,一起來看看吧!
  • 光的小實驗-鏡子的反射
    光的鏡面反射: 光到達鏡面,經過反射進入我們眼睛,我們看到的是等大等距離上下相同的影像,但是左右是相反的。
  • 脊髓反射 反射時的測定 反射弧的分析
    將脊動物俯臥固定在蛙板上,沿右大腿股二頭肌與半膜肌之間的坐骨神經溝剪開大腿後麵皮膚,用玻璃分針分離股二頭肌與半膜肌間的結締組織,暴露坐骨神經,在神經下穿雙線備用(線已用生理鹽水浸溼),並在神經的深面墊一浸蠟紙片。用蛙嘴夾夾住蟾蜍下頜(或用大頭針鉤住動物的下頜),懸掛在鐵支架上。將燒杯盛滿清水。
  • 聊聊玻璃質感(一)|反射、折射
    所以今天我們一起來聊一聊,如何表現出玻璃的質感。  1. -估計是在小學同一堂課上我們也學習過光在兩種物質分界面上改變傳播方向又返回原來物質中的現象叫做光的反射對於玻璃材質而言其表面的反射現象可以理解為通過玻璃表面能觀察到與相機同側的物體所成鏡像
  • 《光的反射》知識歸納
    光的反射:光在傳播到不同物質時,在分界面上改變傳播方向又返回原來物質中的現象。2. 基本概念:一點、二角、三線一點:即入射點,入射光線與鏡面的交點O叫入射點,入射點也是反射點。二角:入射角即入射光線與法線的夾角,常用「i」表示;反射角即反射光線與法線的夾角,常用「r」表示。
  • 什麼是瞳孔對光反射的直接和間接反射
    #醫生請回答#瞳孔大小隨光照強度而變化的反應是一種神經反射,稱為瞳孔對光反射。瞳孔的大小可以控制進入眼內的光量。該反射的感受器為視網膜,傳入神經為視神經,中樞為中腦的頂蓋前區,效應器是虹膜。用拇指和食指將上、下眼險分開露出眼球,用手電筒光照射瞳孔,瞳孔立即變小,移開光源或閉合雙眼,瞳孔即可復原。觀察瞳孔的直接反射和間接對光反射,瞳孔對光反應的特點是效應的雙側性,瞳孔在光照下,引起孔徑變小,稱為直接對光反射。如光照另一眼,非光照眼的瞳孔引起縮小,稱為間接對光反射。
  • 2019中考物理光的反射
    還有凸面凹面鏡,反光作用不一樣;凹面鏡能會聚光,來把燈碗灶臺當; 觀後鏡使光發散,擴大視野任車轉。」 常見考法 近幾年中考試題對這部分的考查,基本以綜合性不高的選擇題、填空題和常規實驗題出現,側重基礎知識的考查;達到「理解」層次的考點有:光的反射定律、光的折射定律。
  • 大海是反射天空的藍色?
    中年人蹲下來,牽著小男孩的手,猶豫了一會兒說:「這是因為海水反射了天空的藍色。」多年的科學研究中,拉曼對英國物理學家瑞利 (注一) 關於光的散射 (注二) 的理論產生了懷疑。瑞利通過實驗得出一個結論,即太陽光遇到大氣分子後,紅色光大部分被吸收,藍色光大部分被散射,所以天空一般呈藍色;他進一步推斷說,之所以海水沒有顏色,看起來是藍色,是因為反射了天空的顏色。
  • 反射弧的分析
    不知道是否還記得反射弧的組成是哪些,反射弧的組成包括5個部分,感受器、傳入神經、神經中樞、傳出神經和效應器。反射弧的任何一個部分被破壞則反射活動不能完成。3)刺激右後肢腳趾,觀察有無屈曲反射,再用清水洗淨硫酸。4)取下牛蛙,剪開右後肢大腿背面半膜肌與股後三頭肌之間的皮膚(皮膚外可看到明顯的分界線),掰開半膜肌與股三頭肌,用玻璃分針分離坐骨神經,在坐骨神經下穿兩根浸潤過任氏液的絲線,兩根線相距1cm結紮,在中間剪斷神經。
  • 兩面鏡子間發射一束光,光會不會一直反射下去?
    鏡面反射的反射率達不到100%,光的能量與反射次數呈指數衰減,由於光速非常快,所以一束光在瞬間就會衰減為零,不可能一直存在下去。 在小時候,如果我們有一塊鏡子,會玩得不亦樂乎,因為利用鏡子可以把太陽光反射到其他地方;我們假設有兩塊大的鏡子,那麼一束光在鏡子之間能無限反射嗎?
  • 光的反射
    【知識點】1.光的反射反射現象:反射現象:光遇到桌面
  • Java 反射最佳實踐
    我們之前寫反射都是要這麼寫:public static <T> T create(HttpRequest httpRequest) {        Object httpRequestEntity = null;        try {            Class&
  • 黑體,只吸收外來輻射提高溫度並放出輻射,不反射外來輻射!
    這說的是,任何有溫度的物體,都會輻射出一定頻率的電磁波;而根據熱力學第三定律,絕對0度是不可能的,所以也可以說任何物體都會有電磁輻射,這種由物體溫度決定的電磁輻射就叫熱輻射。接下來我們將不斷地跟「電磁」、「光」、「輻射」、「波動」這些東東打交道,所以這裡稍微說開一點。
  • 星太奇:古老師不是笑點太高,只是「反射弧」可繞地球一圈!
    星太奇:古老師不是笑點太高,只是「反射弧」可繞地球一圈!上回說到星太奇等人在學校講鬼故事被古老師抓包,還要被罰跑操場100圈和請家長,唯一可以逃避懲罰的方法就是用一個笑話逗樂古老師,結果奮豆和小桂子都失敗了,事到如今只能由星太奇出場瞭然而星太奇的笑話結果還是只能逗樂自己
  • 簡析:Java反射、Java反射定義、反射的基石
    Java反射定義在程序運行過程中,對於任意一個類,可以獲得該類的屬性和方法;對於任意一個對象,可以調用該對象的任意一個屬性和方法。在運行時動態獲取類的信息和動態調用對象的屬性和方法稱為Java反射機制。
  • 和平精英地宮稜鏡反射怎麼玩?地宮稜鏡反射玩法攻略[多圖]
    和平精英地宮稜鏡反射如何過關?地宮稜鏡反射如何操作?地宮新模式開啟後,有好多玩家在稜鏡這個地方卡住了,不知道該如何通過。看名字就應該知道稜鏡的作用就是反光,通過控制稜鏡將光源自動到機關哪裡就可以開啟地宮的大門了。具體操作接下來為大家一一奉上。
  • 散射與反射
    毫無疑問,散射與反射都跟光有關,而光是塑造物體外形最重要的媒介,是攝影前期的必備條件。廣大熱衷拍攝風景的影友,在空氣品質好時拍攝到的藍天,就是由於大氣層中的顆粒物與非常小的水汽分子,吸收波長較短的藍光並折射,形成了我們所見的「藍天」,成為最佳「背景布」。戀綠  戰群 攝點評:綠葉與鐵索,暗喻鮮嫩與恆久、柔軟與堅硬。光線照射在葉子上,象徵更加旺盛的生命力。
  • 1000℃以上的光照到鏡子上,光會被反射?還是將鏡子烤化?
    太陽作為太陽系的老大,可以說是地球的萬物之源,地球上的萬物生靈,風雨變幻,都是太陽的力量,如此強大的力量,哪怕只凝聚一點,也是可以燒穿鋼鐵的,小時候大家應該都玩過放大鏡,當把陽光凝聚到一點時,可以瞬間引燃木頭和紙片,老外愛做各種作死實驗,他們腦洞大膽子大,愛看我們節目的小夥伴肯定都有所了解,這次的老外拿來了一個菲涅爾透鏡,其原理和放大鏡差不多,老外打算和他的女友一起做個實驗
  • 如何解釋反射、散射、吸收?
    如何解釋反射、散射、吸收?盧達晨中學地理問答地理問答 有問必答答:講大氣知識時,涉及大氣對太陽輻射的反射、散射、吸收。反射,抓住「反」字,強調返回、相反方向。散射,當然是看「散」字,與反射相區別,強調散向不同的方向。吸收,強調進去出不來。
  • 神經反射的原理
    (二)反射弧任何反射活動都有一定的結構基礎,即反射弧。反射弧由五部分組成依次為感受器、傳入神經、反射中樞、傳出神經和效應器。反射中樞是在中樞神經系統中調節某一特定生理功能的神經元群,是反射活動最複雜、最關鍵的環節。反射越簡單,反射中樞所在部位越局限,反射越複雜,則中樞分布越廣泛。例如,瞳孔對光反射的中樞局限在中腦,而呼吸反射中樞則位於脊髓、延髓、腦幹及大腦皮層。