2011-07-12 87 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);