Java反射常用到的幾個方法,獲取Private欄位,執行其他類的方法,獲取類名
阿新 • • 發佈:2019-01-25
1.引言
已經很久沒有寫過Java程式碼了,寫了一年的的C++,今天看到C++的friend(友元)可以操作一個類的private屬性,突然想到Java的反射,今天用Java寫了一小段程式碼實驗了一下,專案中比較實用。也是在以前做安卓的專案的時候老是聽到師傅說反射,沒怎麼用過,終於嘗試了一下。
2.程式碼片段
Java的反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法。對於任意一個物件,都能夠呼叫它的任意一個方法和屬性。這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為Java語言的反射機制。
下面來看看我的程式碼片段:
package cn.reflect.demo;
/**
* 描述:實驗Java的反射機制(部分)
* 作者:某種意境丶
* */
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Reflect {
public static void main(String[] args) {
/** 1. 通過反射來呼叫一個類的方法 */
Class<?> data = null;
try {
data = Class.forName("cn.reflect.demo.Data");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
// 呼叫Data類的print方法
Method method = data.getMethod("print");
System.out.print("通過反射來呼叫一個類的方法:");
// invoke的洋文意思就是 呼叫
method.invoke(data.newInstance());
} catch (Exception e) {
e.printStackTrace();
}
/** 2. 檢視類名 */
Data newData = new Data();
System.out.print("完整的包名+類名:");
System.out.println(newData.getClass().getName());
/** 3. 通過反射來獲取一個類的private欄位 */
Object obj = null;
try {
obj = data.newInstance();
Field field = data.getDeclaredField("cnName");
// 這裡設定訪問許可權為true
field.setAccessible(true);
// 為欄位設定新內容
//field.set(obj, "某種意境丶");
String privateField = (String) field.get(obj);
System.out.print("獲得的Private欄位的值是:");
System.out.println(privateField);
} catch (Exception e) {
e.printStackTrace();
}
}
}
檢視列印:
在訪問私有屬性的時候,field.setAccessible(true)的設定是很關鍵的,它把許可權設定為true,從而讓物件能夠操作那個類的私有欄位,類似get/set操作。
public void setAccessible(boolean flag) throws SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
setAccessible0(this, flag);
}
這是setAccessible的Java原始碼,可以看到有一個SecurityManager類來管理這些許可權,具體的可以自己再檢視Java原始碼怎麼實現,這對自己的code能力也是很有幫助的。
如果不知道怎麼檢視Java原始碼,可以參考這篇文章:http://blog.csdn.net/dinghqalex/article/details/43764607