【Java】java使用反射訪問物件方法和成員變數
阿新 • • 發佈:2019-02-15
雖然java是一門靜態語言,但是java的反射機制卻給java提供了很強大的動態特性,其特點是能讓java支援在執行時才能得知名稱與內部結構的類,並能訪問其所有的方法和成員變數,包括私有方法和私有成員變數。下面我寫了一個比較簡潔的測試程式碼,供參考和使用。
測試類
//OBClass.java package com.obo.javaassistdemo; public class OBClass { public int publicField= 999; private int privateField = 234; public static void main(String[] args) { System.out.println("hello world" + new OBClass().privateField); new OBClass().privateMethod(); } public void publicMethod() { System.out.println("test public method"); } public void publicMethodWithParam(String param) { System.out.println("test publicMethodWithParam's param is " + param); } private void privateMethod() { System.out.println("test private method"); } public static void staticMethod() { System.out.println("test static method"); } }
利用反射來呼叫測試類的方法和成員變數。
//JavaAssistDemo.java package com.obo.javaassistdemo; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javassist.CannotCompileException; import javassist.NotFoundException; /** * Created by obo on 16/2/5. */ public class JavaAssistDemo { public static void main(String []args) throws NotFoundException, CannotCompileException, IOException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { reflex(); } //反射 private static void reflex() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException { //建立一個OBClass例項物件 OBClass obClass = new OBClass(); //獲取OBClass的類物件 Class myClass = OBClass.class; /// 無引數的public方法 //反射回去OBClass中的方法名為publicMethod的方法 Method publicMethod = myClass.getDeclaredMethod("publicMethod"); //更改publicMethode方法的可訪問屬性為public //訪問publicMethod方法 publicMethod.invoke(obClass); /// 帶引數的public方法 //反射回去OBClass中的方法名為publicMethod的方法 Method publicMethodWithParam = myClass.getDeclaredMethod("publicMethodWithParam",String.class); //更改publicMethode方法的可訪問屬性為public //訪問publicMethod方法 publicMethodWithParam.invoke(obClass,"hello"); /// 無引數的private方法 //反射回去OBClass中的方法名為publicMethod的方法 Method privateMethod = myClass.getDeclaredMethod("privateMethod"); //更改privateMethod方法的可訪問屬性為public,要想訪問private方法必須要修改這一項 privateMethod.setAccessible(true); //訪問privateMethod方法 privateMethod.invoke(obClass); /// 無引數的static方法 //反射回去OBClass中的方法名為publicMethod的方法 Method staticMethod = myClass.getDeclaredMethod("staticMethod"); //訪問static方法,靜態方法的時候可以使用類物件作為引數 staticMethod.invoke(myClass); /// 獲取public 成員變數 Field publicField = myClass.getDeclaredField("publicField"); publicField.setAccessible(true); System.out.println("" + publicField.getInt(obClass)); /// 獲取private 成員變數 Field privateField = myClass.getDeclaredField("privateField"); privateField.setAccessible(true); System.out.println("" + privateField.getInt(obClass)); } }
上面分別提供了多種方法和成員變數的訪問方式,可以組合起來進行使用。
有了java的反射機制,我們可以實現非常有意思也非常靈活的功能,比如說可以使用java類來建立資料庫表的對映、也可以與javaassist的聯合起來用於修改第三方api等。