我一直在尝试 Java 中的反射...但我有点困惑。
我希望下面的程序允许我更改类中公共(public)成员变量的值。但是,我收到 IllegalArgumentException。有什么想法吗?
public class ColinTest {
public String msg = "fail";
public ColinTest() { }
public static void main(String args[]) throws Exception {
ColinTest test = new ColinTest();
Class c = test.getClass();
Field[] decfields = c.getDeclaredFields();
decfields[0].set("msg", "success");
System.out.println(ColinTest.msg)
}
}
我收到此消息 -
Exception in thread "main" java.lang.IllegalArgumentException
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:37)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:57)
at java.lang.reflect.Field.set(Field.java:656)
at ColinTest.main(ColinTest.java:44)
谢谢。
最佳答案
Field.set
的第一个参数方法应该是您正在反射(reflection)的对象。
decfields[0].set("msg", "success");
应该阅读:
decfields[0].set(test, "success");
此外, final System.out.println
调用应引用test
对象而不是类ColinTest
,因为我认为目的是输出 test.msg
的内容字段。
更新
正如 toolkit 所指出的和 Chris , Class.getDeclaredField
方法可用于指定字段的名称以便检索它:
Field msgField = test.getClass().getDeclaredField("msg");
// or alternatively:
Field msgField = ColinTest.class.getDeclaredField("msg");
然后,set
msgField
的方法可以这样调用:
msgField.set(test, "success");
这种方式有它的好处,正如工具包已经指出的那样,如果有更多字段添加到对象中,Class.getDeclaredFields
返回的字段的顺序不一定会返回字段 msg
作为数组的第一个元素。当对类进行更改时,根据返回数组的顺序,某种方式可能会导致问题。
因此,使用 getDeclaredField
可能是一个更好的主意。并声明所需字段的名称。
关于java - 设置公共(public)成员时出现 IllegalArgumentException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/919962/