9

我正在开发一个使用反射来获取正在运行的 java 应用程序的字段的项目。

我设法获得了这些字段,但我无法读取或写入它们。这是我在网上找到的一个例子:

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

问题是我使用了正在运行的 jar 文件中的类,而我尝试操作的类是从 classLoader 中获取的。所以我只有“.class”而不是“MyObject.class”。为了获得“MyObject”,我尝试使用 ClassLoader 但这不起作用。

如果我只使用'.class':

Object value = field.get(theLoadedClass);

我会收到这个错误:

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

谢谢。

4

6 回答 6

5

这应该有助于:

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);
于 2011-07-12T07:24:09.333 回答
2

从文档中: java.lang.IllegalArgumentException 被抛出:

如果在可能的展开之后,新值无法通过标识或扩展转换转换为基础字段的类型,则该方法将引发 IllegalArgumentException。

这意味着您尝试将字段设置为的对象类型 (Object) 无法转换为实际类型。尝试不要在那里使用对象。

不相关,看看你的代码我会改变

Class aClass = MyObject.class; 

一块:

Class aClass = Class.forName("fullyQualifiedMyObjectClassName.e.g.com.bla.bla.MyObject");
于 2011-07-12T07:28:40.147 回答
2

您需要一个适当类的实例来传递给 field.get/set 方法。

要从 a 获取实例,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); 
于 2011-07-12T07:19:54.147 回答
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);
于 2011-07-12T11:57:08.193 回答
0

您的问题不是很清楚,但我认为您是在问如何使用反射从对象中读取字段的值。

如果您查看 Field.get 的 JavaDoc,您将看到 Field.get 的参数应该是您尝试从中读取字段的对象实例(而不是 Class 对象)。所以它应该是这样的:

Object value = field.get(someInstanceOfTheLoadedClass);

您的错误似乎是尝试将 Class 类型的内容分配给 int 类型的字段的结果。您应该使用Field.setInt来设置 int 字段。

使用 .class 还是使用 Class.forName 获取 Class 对象都没有关系。

于 2011-07-12T07:17:46.880 回答
0

如果您在编译时不知道类型,请使用:

Class = objectInstance.getClass();

同样正如其他海报所说,您必须知道该字段是什么类型并相应地使用正确的类型。

要确定此运行时,请使用 Field.getType() 并在此之后使用正确的 getter 和 setter。

于 2011-07-12T07:21:21.687 回答