java - 设置公共(public)成员时出现 IllegalArgumentException

标签 java reflection

我一直在尝试 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/

相关文章:

java - ClassNotFoundException,怎么办?

Java 可观察接口(interface)

c# - 如何在给定 Dictionary<TKey,TValue> 类型的情况下获取 TKey 和 TValue 的类型

c# - 如何创建具有多个方法调用的 ExpressionTree

java - spring boot缓存redis,key有\xac\xed\x00\x05t\x00\x06

java - 生成的 html 显示 ?而不是国际字符

java - 如何使用 Json 对象的动态属性名称

java - 使用方法句柄转发对功能接口(interface)的调用

c# - 将扩展方法与运行时程序集一起使用

java - 使用反射和 ClassLoaders 创建类的实例时出现 ClassCastException