我們經常使用COMMONS-BEANUTILS包來進行bean的操作,例如從map到bean獲從bean到map的映射,那麼實現的原理是什麼呢,下面舉個簡單的操作的例子;首先,我建立一個bean
public class Bean {
private String test1;
private String getTest1() {
return test1;
}
private void setTest1(String test1) {
this.test1 = test1;
}
}
上面這個例子比較極端,利用我們平常的JAVA操作是不可能通過這兩個私人方法進行設定和擷取值的,但是我們利用JAVA反射機制卻可以非常方便的操作。
下面,我將全部利用JAVA的反射來進行對象的建立,以及對它的操作;這裡我們假設這個Bean我們只能得到名稱,例如,我們是從設定檔中得到的名稱,公司的COMMAND架構中receiver的配置就是如此,配置了receiver的名稱和要執行的方法,我們無論他是否是私人的還是共有的都可以訪問。
public class TestClass {
/**
* @param args
* @throws ClassNotFoundException
* @throws NoSuchMethodException
* @throws SecurityException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InstantiationException
*/
public static void main(String[] args) throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException {
//1.0得到bean的Class對象
Class beanClass=Class.forName("org.test.t.Bean");
//2.0利用建構函式構造一個Bean對象
Constructor bc=beanClass.getConstructor(null);
Bean b=(Bean) bc.newInstance(null);
/**
* 也可以這樣構造
* Bean b=Class.forName("org.test.t.Bean").newInstance();
*/
//3.0通過getDeclaredMethod方法得到要執行的方法(public/protected/private/預設),要執行的方法的函數名字是第一個參數指定,第二個參數指定該函數帶有的參數
//如果只需要得到公用成員方法,則直接調用getMethod方法
Method setMethod=beanClass.getDeclaredMethod("setTest1", new Class[]{String.class});
Method getMethod=beanClass.getDeclaredMethod("getTest1", null);
//4.0 如果要訪問私人的方法,所以我們在這裡將可訪問設定為true,則JVM不會執行存取控制檢查;如果是共有方法則不需要設定
setMethod.setAccessible(true);
//5.0用得到的方法對象在第2步中構造的對象中執行
setMethod.invoke(b, new Object[]{"hello"});
System.out.println(getMethod.isAccessible());
getMethod.setAccessible(true);
System.out.println(getMethod.isAccessible());
System.out.println(getMethod.invoke(b, null));
}
}
上面紅色部分是擷取所有public/private/protected/預設 方法的函數,如果只需要擷取public方法,則可以調用getMethod.
上麵粉紅色的方法是將要執行的方法對象設定是否進行訪問檢查,也就是說對於public/private/protected/預設 我們是否能夠訪問。值為 true 則指示反射的對象在使用時應該取消 Java 語言訪問檢查。值為 false 則指示反射的對象應該實施 Java 語言訪問檢查。
如果是共有方法,當然不需要設定。