java Java反射题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6660562/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java reflection question
提问by Natan Griefwell
I am working on a project that uses reflection to get the fields of a running java application.
我正在开发一个项目,该项目使用反射来获取正在运行的 Java 应用程序的字段。
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.
问题是我使用了正在运行的 jar 文件中的类,而我尝试操作的类是从 classLoader 获取的。所以我只有“.class”而不是“MyObject.class”。为了获得“MyObject”,我尝试使用 ClassLoader,但这不起作用。
If I just use '.class':
如果我只使用“.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.
谢谢。
回答by JB-
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);
回答by Nikola Yovchev
From the documentation: java.lang.IllegalArgumentException is thrown:
从文档: 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.
如果在可能的展开之后,新值无法通过标识或扩展转换转换为基础字段的类型,则该方法将引发 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.
这意味着您尝试将字段设置为的对象类型(Object)无法转换为实际类型。尽量不要在那里使用对象。
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");
回答by Bohemian
You need an instance of the appropriate class to pass into the field.get/set methods.
您需要一个适当类的实例来传递给 field.get/set 方法。
To get an instance from a class
you can try these options:
要从 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);
回答by jontro
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.
要确定此运行时,请使用 Field.getType() 并在此之后使用正确的 getter 和 setter。
回答by Mathias Schwarz
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:
如果您查看 Field.get 的 JavaDoc,您将看到 Field.get 的参数应该是您尝试从中读取字段的对象实例(而不是 Class 对象)。所以它应该是这样的:
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.setIntto set int fields.
你的错误似乎是试图将 Class 类型的东西分配给 int 类型的字段的结果。您应该使用Field.setInt来设置 int 字段。
It doesn't matter whether you obtain the Class object by using .class or by using Class.forName.
使用 .class 还是使用 Class.forName 获取 Class 对象并不重要。
回答by M.L.
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);