ITEEDU

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);

当然即使类别在定义时被宣告为私有,就表示不希望您存取它,若要透用反射机制来突破这个限制,则您要清楚您在作些什么。