跟我學Java反射——一步曲

來源:互聯網
上載者:User

標籤:java 反射

反射是什麼

 

    Reflection(反射)就是Java程式在運行時可以動態得到程式內部所有類的內部資訊,並能動態調用任意對象的內部屬性和方法。

 

為什麼需要反射

 

    我們為什麼要用反射,這主要是反射的動態性決定的,由於反射可以實現動態建立對象,這就很大程度發揮了java的靈活性,降低了程式調用的耦合性,使系統可以更加的靈活,可以更好的應對變化。

 

反射應用


運行反射我們可以做到:

 

    在運行時判斷任意一個對象所屬的類

    在運行時構造任意一個類的對象

    在運行時判斷任意一個類所具有的成員變數和方法

    在運行時調用任意一個對象的成員變數和方法

    產生動態代理

 

跟反射相關的常用類主要有:

 

    java.lang.Class:代表一個類

    java.lang.reflect.Method:代表類的方法

    java.lang.reflect.Field:代表類的成員變數

    java.lang.reflect.Constructor:代表類的構造方法

 


Class類

 

    Class類是反射機制的源頭,實際上所謂的反射從程式的運行結果來看就是,通過對象反射擷取類的名稱。

 

反射其實是類正常方式使用的反過程就像物理學中的反射一樣:

 


 

 

    通過反射我們可以得到的資訊:某個類的屬性、方法、構造器、類實現了哪些介面、父類是什麼。對於每個類而言,JRE都為其保留了一個不變的Class類型的對象,一個Class對象包含了特定某個類的有關資訊。

 

    Class本身也是一個類,每個類在JVM中只有有一個Class執行個體,每個Class對象對應的是一個載入到JVM中的一個.class檔案,每個類的執行個體都會記得自己是由哪個Class執行個體所產生的。

 


通過反射得到Class類對象,四種方式

 

    我們現在有一個建立好的類Person,類路徑是package com.tgb.reflect.common;

 

    1.已知具體Person類,通過Person類的class屬性擷取,該方法最為安全可靠,程式效能最高。

 

@Testpublic void test1(){Classclass1 = Person.class;System.out.println(class1);}


 

 

    2.已知Person類的執行個體,調用該執行個體的getClass()方法擷取Class對象

 

@Testpublic void test2() {Personp = new Person();Classclass1 =p.getClass();System.out.println(class1);}


 

 

    3.已知Person類的全類名,且該類在類路徑下,可通過Class類的靜態方法forName()擷取。

 

@Testpublic void test3()throws ClassNotFoundException{StringclassName = "com.tgb.reflect.common.Person";Classclass1 = Class.forName(className);System.out.println(class1);}


 

 

    4.通過類載入器來擷取Class對象。

 

@Testpublic void test4()throws ClassNotFoundException{StringclassName= "com.tgb.reflect.common.Person";ClassLoaderclassLoader =this.getClass().getClassLoader();Classclass1=classLoader.loadClass(className);System.out.println(class1);}


 

 

    以上四種方式得到Class對象的代碼經運行得到的結果是一樣的,運行結果是"classcom.tgb.reflect.common.Person"; 

 

 

類載入器

 

    當我們程式主動使用某個類時,如果該類還未被載入到記憶體中,則系統會通過如下三個步驟來對該類進行初始化。

 


 

 

    ClassLoader(類載入器)是用來把類(.class)裝在進入記憶體的,JVM在運行時會產生3個類載入器組成的初始化載入器階層 ,如所示:

 


 

 

    我們通過代碼來看下:

 

@Testpublic void test1()throws ClassNotFoundException{ //1.擷取一個系統類別載入器ClassLoaderloader1  =ClassLoader.getSystemClassLoader();System.out.println("系統類別載入器為:"+loader1); //2.擷取系統類別載入器的父類載入器,即擴充類載入器ClassLoaderloader2 = loader1.getParent();System.out.println("擴充類載入器:"+loader2); //3.擷取擴充類載入器的父類載入器,即引導類載入器ClassLoaderloader3 = loader2.getParent();System.out.println("引導類載入器:"+loader3); //4.測試當前類由哪個類載入器進行載入Classclass1 = Person.class;ClassLoaderloader4= class1.getClassLoader();System.out.println("當前類的類載入器:"+loader4); //5.測試JDK提供的String類由哪個類載入器載入StringclassName= "java.lang.String";Classclass2 = Class.forName(className);ClassLoaderloader5= class2.getClassLoader();System.out.println("JDK提供的String類載入器:"+loader5); }


 

運行結果為:


    系統類別載入器為:[email protected]

    擴充類載入器:[email protected]

    引導類載入器:null

    當前類的類載入器:[email protected]

    JDK提供的String類載入器:null

 

    由代碼運行結果我們可以看到,我們自己定義的類是由系統類別載入器載入的、系統類別載入器上一級是擴充類載入器、擴充類載入器上一級系統不允許我們拿到,但是擴張類載入器上一級確實是引導類載入器,這類載入器主要是用來載入jvm內建的類庫的。

 

    關於類載入器有時候我們可以用來讀取系統中的設定檔,下面我們就個簡單的小例子,我們將一個Test.properties檔案放到我們的類目錄中,我們用類載入器來讀取其中的內容。

 

我們設定檔的內容很簡單:


    user=root

    password=123456

 

    代碼如下:

@Testpublic void test2()throws IOException{//獲得類載入器ClassLoaderclassLoader = this.getClass().getClassLoader(); //運用類載入器讀取property檔案到輸入資料流中StringfilePath = "com\\tgb\\reflect\\test1\\Test.properties";InputStreaminputStream = ClassLoader.getSystemResourceAsStream(filePath); //擷取檔案內容Propertiesproperties =new Properties();properties.load(inputStream);Stringuser=properties.getProperty("user");System.out.println("user:"+user);Stringpassword = properties.getProperty("password");System.out.println("password:"+password); } 


運行結果是:


    user:root

    password:123456

 


後記


    這篇文章介紹了反射的基本知識,還有反射的源頭Class類,並講述了得到Class類對象的四種方式,同時還介紹了類載入器的一些知識,關於反射這篇文章就先介紹這麼多,下篇文章我們繼續。

跟我學Java反射——一步曲

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.