From Gossip@Openhome

Java Gossip: 修改成員值

儘管直接存取Field成員是不被鼓勵的,但您仍是可以直接操作公開的(public)Field成員,而您也可 以透過動態載入的方式來操作Field成員,這邊以一個實例來說明,首先撰寫個TestedField類別:
  • TestedField.java
package onlyfun.caterpillar;

public class TestedField {
public int testInt;
public String testString;

public String toString() {
return testInt + " " + testString;
}
}

再來看看如何透過動態載入來存取Field成員:
  • AssignFieldDemo.java
package onlyfun.caterpillar;

import java.lang.reflect.Field;

public class AssignFieldDemo {
public static void main(String[] args) {
try {
Class c = Class.forName(args[0]);
Object targetObj = c.newInstance();

Field testInt = c.getField("testInt");
testInt.setInt(targetObj, 99);

Field testString = c.getField("testString");
testString.set(targetObj, "caterpillar");

System.out.println(targetObj);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}

執行結果:
java onlyfun.caterpillar.AssignFieldDemo onlyfun.caterpillar.TestedField
99 caterpillar


呼叫方法 中介紹了如何存取私有的(private)方法,同樣的道理,如果必要,仍是可以透過反射機制來存取私有的Field成員,例如:
Field privateField = c.getDeclaredField("privateField");
privateField.setAccessible(true);
privateField.setInt(targetObj, 99);
 
當然即使類別在定義時被宣告為私有,就表示不希望您存取它,若要透用反射機制來突破這個限制,則您要清楚您在作些什麼。