使用reflection设置私有字段值

我有两个class: FatherChild

 public class Father implements Serializable, JSONInterface { private String a_field; //setter and getter here } public class Child extends Father { //empty class } 

有了reflection,我想在Child类中设置a_field

 Class clazz = Class.forName("Child"); Object cc = clazz.newInstance(); Field f1 = cc.getClass().getField("a_field"); f1.set(cc, "reflecting on life"); String str1 = (String) f1.get(cc.getClass()); System.out.println("field: " + str1); 

但我有一个例外:

线程“main”中的exceptionjava.lang.NoSuchFieldException:a_field

但如果我尝试:

 Child child = new Child(); child.setA_field("123"); 

有用。

使用setter方法我有同样的问题:

 method = cc.getClass().getMethod("setA_field"); method.invoke(cc, new Object[] { "aaaaaaaaaaaaaa" }); 

要访问私有字段,您需要将Field::setAccessible设置为true。 你可以从超类中拉出场地。 此代码有效:

 Class clazz = Child.class; Object cc = clazz.newInstance(); Field f1 = cc.getClass().getSuperclass().getDeclaredField("a_field"); f1.setAccessible(true); f1.set(cc, "reflecting on life"); String str1 = (String) f1.get(cc); System.out.println("field: " + str1); 

使用Apache commons-lang3:

 FieldUtils.writeField(childInstance, "a_field", "Hello", true); 

“真实”迫使它设定,即使是“私人”。

这个也可以访问私有字段而无需做任何事情

 import org.apache.commons.lang3.reflect.FieldUtils; Object value = FieldUtils.readField(entity, fieldName, true); 

根据Class.getField的Javadoc(强调我的):

返回一个Field对象,该对象反映此Class对象所表示的类或接口的指定公共成员字段

此方法仅返回公共字段。 由于a_field是私有的,因此无法找到。

这是一个有效的代码:

 public class Main { public static void main(String[] args) throws Exception { Class clazz = Class.forName("Child"); Object cc = clazz.newInstance(); Field f1 = cc.getClass().getField("a_field"); f1.set(cc, "reflecting on life"); String str1 = (String) f1.get(cc); System.out.println("field: " + str1); } } class Father implements Serializable { public String a_field; } class Child extends Father { //empty class } 

请注意,我还更改了你的行String str1 = (String) f1.get(cc.getClass()); to String str1 = (String) f1.get(cc); 因为你需要给出字段的对象,而不是类。


如果要将字段保密,则需要检索getter / setter方法并调用它们。 你给出的代码不起作用,因为要获得一个方法,你还需要指定它的参数,所以

 cc.getClass().getMethod("setA_field"); 

一定是

 cc.getClass().getMethod("setA_field", String.class); 

这是一个有效的代码:

 public class Main { public static void main(String[] args) throws Exception { Class clazz = Class.forName("Child"); Object cc = clazz.newInstance(); cc.getClass().getMethod("setA_field", String.class).invoke(cc, "aaaaaaaaaaaaaa"); String str1 = (String) cc.getClass().getMethod("getA_field").invoke(cc); System.out.println("field: " + str1); } } class Father implements Serializable { private String a_field; public String getA_field() { return a_field; } public void setA_field(String a_field) { this.a_field = a_field; } } class Child extends Father { //empty class }