Java反射-1
阿新 • • 發佈:2021-09-08
1.基本概念
a.編譯器與執行期
- 編譯期:把原始碼交給編譯器編譯成計算機可以執行的檔案的過程(Java程式碼程式設計.class檔案的過程),只是做了一些翻譯功能。
- 執行期:將編譯後的檔案交給計算機執行直至程式執行結束。(在磁碟中的程式碼放到記憶體中執行起來)
b.Java反射機制概念及作用
-
Java反射機制: 動態獲取資訊以及動態呼叫物件方法的功能。在執行狀態中,對於任意一個類,都能知道這個類的所有屬性以及方法;對於任意一個物件,都能夠呼叫它的任意方法和屬性。
-
Java反射機制在伺服器程式和中介軟體程式中應用廣泛(伺服器端根據客戶請求動態呼叫某個物件的特定方法)。
c.Java反射機制提供的主要功能
- 執行時判斷任意一個物件所屬的類。
- 執行時構造任意一個類的物件。
- 執行時判斷任意一個類所具有的成員變數和方法。
- 執行時呼叫任意一個物件的方法。
- 生成動態代理。(關於動態代理見 https://www.jianshu.com/p/9bcac608c714)
下表:反射可訪問的常用資訊
d.Java反射機制的優缺點
優點
- 能夠執行時動態獲取類的例項,大大提高系統的靈活性和擴充套件性
- 與Java動態編譯相結合,可以實現無比強大的功能
- 對於Java這種先編譯後執行的而語言,能讓我們很方便的建立靈活的程式碼。這些程式碼可以在執行時裝配,無需在元件之間進行原始碼的連線,更加容易實現面向物件。
缺點
- 反射會消耗一定的系統資源(不需動態建立物件時不必使用反射)
- 反射呼叫方法時可以忽略許可權檢查獲取類的私有方法和屬性,可能會破環類的封裝性導致安全問題。
2.Java反射機制API
java.lang.Class類(實現反射的關鍵所在)
- Class類的一個例項表示Java的一種資料型別(類、介面、列舉、註解、陣列、基本資料型別、void)。Class無公有構造方法,Class例項是由JVM在類載入時自動建立的。
獲取Class例項的方法
- 每一種型別(類、介面)都有一個class靜態變數可以獲得Class例項
Class clz1 = String.class;
- 每一個物件都有getClass()方法獲得Class例項(Object類提供的例項方法)
String str = "Hello"; Class clz2 = str.getClass();
java.lang.reflect包
- 該包提供了反射用到的類,主要類說明如下:
- Constructor類:提供類的構造方法資訊
- Field類:提供類或介面中成員變數資訊
- Method類:提供類或介面成員方法資訊
- Array類:提供了動態建立和訪問Java陣列的方法
- Modifier類:提供類和成員訪問修飾符資訊
程式碼例項(forName(String))建立某個類的執行時物件,若無則丟擲ClassNotFoundException異常
//動態載入String類的執行時物件
Class c = Class.forName("java.lang.Integer");
//獲取成員方法集合
Method[] methods = c.getDeclaredMethods();
//遍歷成員方法集合
for(Method method: methods){
//列印修飾符
System.out.println(Modifier.toString(method.getModifiers()));
//列印返回值型別名
System.out.println(method.getReturnType().getName() + " ");
//列印方法名
System.out.println(method.getName() + " ");
System.out.println();
3.Java通過反射訪問構造方法
- 為動態獲取物件構造方法的資訊,首先需建立一個Constructor型別的物件或陣列via下列方法之一
- getConstructors()
- getConstructors(Class<?>...parameterTypes)
- getDeclaredConstructors()
- getDeclaredConstructor(Class<?>...parameterTypes)
注:若訪問指定的構造方法,需根據該構造方法的入口引數的型別來訪問。
eg訪問一入口引數為int和String型別的構造方法
objectClass.getDeclaredConstructor(int.class, String.class)
建立的Constructor物件標識一個構造方法,然年後利用Constructor物件的方法操作構造方法。常用方法如下:
對於getModifiers()方法,通過java.lang.reflect.Modifier類可以解析出該方法的返回值所表示的修飾符資訊。
在該類中提供了一系列用來解析的靜態方法,既可以檢視是否被指定的修飾符修飾,還可以字串形式獲得所修飾符。
4.Java通過反射執行方法(獲取方法)
- 要動態獲取一個物件方法的資訊,需通過下列方法之一建立一個Method型別的物件或陣列。
- getMethods()
- getMethods(String name,Class<?>...parameterTypes)
- getDeclaredMethods()
- getDeclaredMethods(String name,Class<?>...parameterTypes)
Method類常用方法如下
注:invoke需先指定物件obj eg.
test1 a = new test1("Mike", 22);
Object obj = method.invoke(a, "baby", "I");
5.Java通過反射訪問成員變數
- 通過下列方法訪問成員變數時將返回Field型別的物件或陣列
- getFields()
- getField(String name)
- getDeclaredFields()
- getDeclaredField(String name)
Field類常用方法如下: