Java基礎 | 反射(學習筆記)
阿新 • • 發佈:2018-11-04
文章目錄
1. 概述
Reflection(反射)是Java被視為動態語言的關鍵,反射機制允許程式在執行期藉助於Reflection API
為什麼要使用反射?
反射的主要作用是在執行時
獲取類資訊和呼叫類方法,如果有些類的的資訊在編譯階段
是不確定,需要到執行時
才確定的情況時,這個時候就需要使用到類的反射了
Java反射機制主要提供以下功能:
- 在執行時判斷任意一個物件所屬的類
- 在執行時構造任意一個類的物件
- 在執行時獲取任意一個類所具有的成員變數和方法
- 在執行時呼叫任意一個物件的成員變數和方法
- 生成動態代理
2. 理解Class類並例項化Class類物件
2.1 理解Class類
在《Java程式設計思想》中,作者告訴我們“萬事萬物皆是物件
當我們需要一個物件的時候,我們的第一想法就是先寫一個類,然後
new
一個物件出來,但是我們有沒有考慮過,既然說“萬事萬物皆是物件”,難道在這裡類就是例外了嗎?它是不是物件呢?
答案是的,我們平時寫的類是java.lang.Class類
的例項物件
在Object
類中定義了以下的方法,此方法將被所有子類繼承:
public final Class getClass()
以上的方法返回值的型別是一個Class
類,此類是Java反射的源頭,實際上所謂反射從程式的執行結果來看也很好理解,即:可以通過物件反射求出類的名稱。
###執行時類的由來
建立一個類—>通過編譯(javax.exe),生成對應的 .class 檔案—> 通過載入(JVM的類載入器完成的java.exe)
此.class 檔案載入到記憶體以後,就是一個執行時類,存在快取區,那麼這個執行時類本身就是一個Class的例項
- Class本身也是一個類
- Class 物件只能由系統建立物件
- 一個類在 JVM 中只會有一個Class例項
- 一個Class物件對應的是一個載入到JVM中的一個.class檔案
- 每個類的例項都會記得自己是由哪個 Class 例項所生成
- 通過Class可以完整地得到一個類中的完整結構
類的載入過程
當程式主動使用某個類時,如果該類還未被載入到記憶體中,則系統會通過如下三個步驟來對該類進行初始化
- 類的載入:將類的class檔案讀入記憶體,併為之建立一個java.lang.Class物件。此過程由類載入器完成
- 類的連線: 將類的二進位制資料合併到JRE中
- 類的初始化:JVM負責對類進行初始化
2.2 獲取Class物件方法(4種)
- 通過執行時類本身的
.class
屬性 - 通過執行時類的物件,呼叫
getClass()
,返回其執行時類 - 通過
Class
的靜態方法獲取 - 通過類的載入器
Class c1 = 類名.class;
Class c2 = 例項物件.getClass();
Class c3 = Class.forName("com.類名");
ClassLoader classLoader = this.getClass().getClassLoader();
Class c4 = classLoader.loadClass("com.類名");
3. 執行時建立類物件並獲取類的完整結構
3.1 建立執行時類的物件
- 呼叫Class物件的newInstance()方法
Class cla = Person.class;
Person p = (Person)cla.newInstance(); //呼叫此方法,必須Person類需要有對應的構造方法(如空參構造器)
System.out.println(p);
4. 通過反射呼叫類的指定方法、指定屬性
這裡只是舉有關於屬性和方法的一個例子,具體的沒有記錄
//1.通過反射呼叫執行時類的指定的屬性、
Field f1 = cla.getField("name");
f1.set(p, "Rose");
System.out.println(p);
//2.通過反射呼叫執行時類的指定的方法
Method m1 = cla.getMethod("show");
m1.invoke(p);