1. 程式人生 > >Java反射常用到的幾個方法,獲取Private欄位,執行其他類的方法,獲取類名

Java反射常用到的幾個方法,獲取Private欄位,執行其他類的方法,獲取類名

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