2014-12-27 111 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