2014-12-27 114 views
-1

我在做什么:获取名为“f3”的类型为“K”的反射字段的值。我希望能够使用f3的值来反映其中的字段。 (编辑)f3位于类b中,它来自.jar文件。 (编辑)反射IllegalArgumentException java

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

问题:如何获得类b(它是从外部jar加载的类)上的字段f3(类型K)的值?

下面的代码引发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. 

堆栈跟踪:

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

您正在尝试检索字段的一个Class<B>实例的值,而不是做它的一个实例在你的代码中,你通过你(非常笨拙)称为instance的代表。需要说明的是,如果f3B类别的一个静态字段(Class<B>的字段确实是B的静态字段),但它实际上是一个非静态字段。因此,你需要调用get方法之前得到的B一个实例:

Class<?> clazz = loadClass("b"); 
Object instance = clazz.newInstance(); 
Fied fieldf3 = B.class.getDeclaredField("f3"); 
fieldf3.setAccessible(true); 
fieldf3.get(instance); 

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

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

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

+0

实例是b.class,b在其内部具有类型为K的字段f3。 b是来自.jar文件 – TKG

+0

实例不是K类 – TKG

+0

是的,在我的代码中,你的K k是我的b实例,而你的int f3是我想要的K f3值,但是field.get(instance)是给出的问题 – TKG