反射IllegalArgumentException java

时间:2014-12-27 02:11:21

标签: java reflection

我想做的是:获取名为" f3"的反射字段的值。类型" K"。我希望能够使用f3的值来反映其中的字段。 (编辑)f3在类b中,来自.jar文件。 (编辑)

获取我尝试的值的所有方法都给出了错误:无法将K字段f3设置为java.lang.Class。

问题:如何在类f3(从外部jar加载的类)中获取字段K(类型为b)的值?

以下代码抛出IllegalArgumentException

Class instance = loadClass("b"); // simplified for readability
Field fieldf3 = instance.getDeclaredField("f3");
fieldf3.setAccessible(true);
Object value = fieldf3.get(instance); //exception on this line.

StackTrace:

java.lang.IllegalArgumentException: Can not set K field b.f3 to java.lang.Class
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
    at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
    at java.lang.reflect.Field.get(Field.java:387)

1 个答案:

答案 0 :(得分:2)

您正在尝试在Class<B>实例上检索字段的值,而不是在代码中使用instance调用类f3的类表示实例。要明确的是,如果B是类Class<B>的静态字段(B的字段确实是B的静态字段),那么您就是这样做的实际上是一个非静态字段。因此,在调用get方法之前,您需要获取Class<?> clazz = loadClass("b"); Object instance = clazz.newInstance(); Fied fieldf3 = B.class.getDeclaredField("f3"); fieldf3.setAccessible(true); fieldf3.get(instance); 的实例:

static class B {
    private int f3;
    public B(int f) {
        f3 = f;
    }
}

public static void main(String[] args) {
    B b = new b(17);
    Field field = B.class.getDeclaredField("f3");
    field.setAccessible(true);
    System.out.println(field.get(b));
}

让我们看一个例子(这次让我们假设B是主文件中定义的类):

17

此代码将按预期输出f3。现在,假设Class<B>是一个静态字段,然后它成为任何System.out.println(field.get(B.class));实例上的字段(实际上,我认为它是一个单例,因此只有一个这样的实例),然后你可以添加B它仍然有用。该字段的值也可以从System.out.println(field.get(b));的任何实例访问,因此{{1}}也可以使用。