Java反射问题

发布于 2024-11-19 08:25:36 字数 658 浏览 3 评论 0原文

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

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

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

问题是我使用正在运行的jar文件中的类,而我尝试操作的类是从类加载器中获取的。因此,我只有“.class”,而不是“MyObject.class”。为了获取“MyObject”,我尝试使用类加载器,但这不起作用。

如果我只使用“.class”:

Object value = field.get(theLoadedClass);

我会收到此错误:

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

谢谢。

I am working on a project that uses reflection to get the fields of a running java application.

I managed to get the fields, but I can not read or write to them. This is an example I found on the web:

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

The problem is that I use classes from a running jar file, and the classes I try to manipulate are obtained from the classLoader. So instead of 'MyObject.class' I just have the '.class'. To get the 'MyObject' I tried to use a ClassLoader but that did not work.

If I just use '.class':

Object value = field.get(theLoadedClass);

I will get this error:

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

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

空心↖ 2024-11-26 08:25:36

这应该有帮助:

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

This should help:

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);
執念 2024-11-26 08:25:36

您需要适当类的实例才能传递到 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); 

You need an instance of the appropriate class to pass into the field.get/set methods.

To get an instance from a class you can try these options:

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); 
逆光飞翔i 2024-11-26 08:25:36

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

如果在可能的解包之后,新值无法转换为
通过恒等或扩展确定基础字段的类型
转换时,该方法会抛出 IllegalArgumentException。

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

无关,查看你的代码我会将其更改

Class aClass = MyObject.class; 

为:

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

From the documentation:
java.lang.IllegalArgumentException is thrown:

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.

This means the object type (Object) you attempt to set the field to cannot be converted to the actual type. Try not using an Object there.

Unrelated, looking at your code I would change the

Class aClass = MyObject.class; 

piece to:

Class aClass = Class.forName("fullyQualifiedMyObjectClassName.e.g.com.bla.bla.MyObject");
魔法少女 2024-11-26 08:25:36

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

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

Object value = field.get(someInstanceOfTheLoadedClass);

你的错误似乎是试图将 Class 类型的东西分配给 int 类型的字段的结果。您应该使用 Field.setInt 设置 int 字段。

使用 .class 或 Class.forName 获取 Class 对象并不重要。

Your questions is not very clear, but I think you are asking how to read the value of a field from an object using reflection.

If you look in the JavaDoc of Field.get you will see that the argument to Field.get should be the object instance you are trying to read the field from (not the Class object). So it should be something like:

Object value = field.get(someInstanceOfTheLoadedClass);

You erros seems to be a result of trying to assign something of type Class to a field of type int. You should use Field.setInt to set int fields.

It doesn't matter whether you obtain the Class object by using .class or by using Class.forName.

蓝天白云 2024-11-26 08:25:36

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

Class = objectInstance.getClass();

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

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

If you do not know the type at compile time use:

Class = objectInstance.getClass();

Also as the other posters said you have to know what type the field is and use the correct type accordingly.

To determine this runtime use Field.getType() and use the correct getter and setter after that.

_畞蕅 2024-11-26 08:25:36

这有效吗?

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

Does this work?

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文