2011-07-12 126 views
6

我正在使用反射來獲取正在運行的Java應用程序的字段的項目。Java反射問題

我設法得到字段,但我無法讀取或寫入他們。這是一個例子,我在網上找到:

Class aClass = MyObject.class 
Field field = aClass.getField("someField"); 
MyObject objectInstance = new MyObject(); 
Object value = field.get(objectInstance); 
field.set(objetInstance, value); 

的問題是,我使用類從運行jar文件,我嘗試操縱類是從類加載器獲得。所以,而不是'MyObject.class',我只是'.class'。爲了得到'MyObject',我嘗試使用一個ClassLoader,但沒有奏效。

如果我只是用」的.class':

Object value = field.get(theLoadedClass); 

我會得到這個錯誤:

java.lang.IllegalArgumentException: Can not set int field myClass.field to java.lang.Class 

感謝。

+0

你是什麼意思的'正在運行的jar文件'?它在你的類路徑上嗎? – wjans

回答

0

你的問題不是很清楚,但我想你是問如何從一個對象中使用反射來讀取字段的值。

如果您查看Field.get的JavaDoc,您會看到Field.get的參數應該是您試圖從(不是Class對象)中讀取字段的對象實例。所以它應該是這樣的:

Object value = field.get(someInstanceOfTheLoadedClass); 

您錯誤似乎是嘗試將類型的類分配給int類型的字段的結果。您應該使用Field.setInt來設置int字段。

無論您是通過使用.class還是使用Class.forName獲取Class對象,都無關緊要。

+0

...或使用'myObject.getClass()'。 –

2

您需要將相應類的實例傳遞給field.get/set方法。

要從class得到一個情況下,你可以嘗試以下幾種:

Class<?> clazz = MyObject.class; 
// How to call the default constructor from the class: 
MyObject myObject1 = clazz.newInstance(); 
// Example of calling a custom constructor from the class: 
MyObject myObject2 = clazz.getConstructor(String.class, Integer.class).newInstance("foo", 1); 
0

如果你不知道在編譯時使用的類型:

Class = objectInstance.getClass(); 

另外,作爲其他海報說你必須知道該字段是什麼類型,並相應地使用正確的類型。

要確定此運行時使用Field.getType()並在此之後使用正確的getter和setter。

3

這應有助於:

Class aClass = myClassLoader.loadClass("MyObject"); // use your class loader and fully qualified class name 
Field field = aClass.getField("someField"); 
// you can not use "MyObject objectInstance = new MyObject()" since its class would be loaded by a different classloader to the one used to obtain "aClass" 
// instead, use "newInstance()" method of the class 
Object objectInstance = aClass.newInstance(); 
Object value = field.get(objectInstance); 
field.set(objetInstance, value); 
2

從文檔: java.lang.IllegalArgumentException異常被拋出:

If, after possible unwrapping, the new value cannot be converted to the type of the underlying field by an identity or widening conversion, the method throws an IllegalArgumentException.

這意味着對象類型(對象),你嘗試設置現場不能轉換爲實際的類型。儘量不要在那裏使用Object。

無關的,看你的代碼,我會改變

Class aClass = MyObject.class; 

一塊:

Class aClass = Class.forName("fullyQualifiedMyObjectClassName.e.g.com.bla.bla.MyObject"); 
0

工作的呢?

Class aClass = MyObject.class; 
Field field = aClass.getDeclaredField("someField"); 
field.setAccessible(true); 
MyObject objectInstance = new MyObject(); 
Object value = field.get(objectInstance); 
field.set(objectInstance, value);