字段的 get(Object obj) 不适用于实例变量
我很困惑为什么 get(Object obj) 不适用于实例变量(实例字段),并抛出 IllegalArgumentException。
我有以下类:
public class InfoSender {
String testInt = "hey";
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
InfoSender test = new InfoSender();
test.asd();
// script g = new script();
// mobile h = new mobile();
}
private void asd() {
new StatusGUI(this);
}
}
并且我有 StatusGUI 类(不包括 initComponents):
public class StatusGUI extends javax.swing.JFrame {
Class clazz;
/** Creates new form StatusGUI */
public StatusGUI(Object invokerObject) {
initComponents();
setVisible(true);
setLocationRelativeTo(null);
clazz = invokerObject.getClass();
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
try {
Field[] fields = clazz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
jTextArea1.append(fields[i].getName() + " | " + fields[i].getType() + " | " + fields[i].get(clazz));
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
按下按钮时,它将成功写入字段的名称并类型。
当我想添加公共字段的价值时,我很快了解到,如果不将它们声明为静态(至少据我所知),这是不可能的。
尽管根据 Java Field Class 文档,该字段可以作为实例字段: http://download.oracle.com /javase/1.4.2/docs/api/java/lang/reflect/Field.html
异常的堆栈跟踪:
java.lang.IllegalArgumentException: Can not set java.lang.String field infosender.InfoSender.testInt to java.lang.Class
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:37)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:18)
at java.lang.reflect.Field.get(Field.java:358)
at infosender.StatusGUI.jButton1ActionPerformed(StatusGUI.java:93)
at infosender.StatusGUI.access$000(StatusGUI.java:22)
at infosender.StatusGUI$1.actionPerformed(StatusGUI.java:54)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6289)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6054)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4652)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4482)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
at java.awt.Container.dispatchEventImpl(Container.java:2085)
at java.awt.Window.dispatchEventImpl(Window.java:2478)
at java.awt.Component.dispatchEvent(Component.java:4482)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:644)
at java.awt.EventQueue.access$000(EventQueue.java:85)
at java.awt.EventQueue$1.run(EventQueue.java:603)
at java.awt.EventQueue$1.run(EventQueue.java:601)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
at java.awt.EventQueue$2.run(EventQueue.java:617)
at java.awt.EventQueue$2.run(EventQueue.java:615)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:614)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
感谢任何帮助:) 麦克风。
I'm puzzled as to why get(Object obj) does not work with instance variables (instance fields), and throws an IllegalArgumentException.
I have the following class:
public class InfoSender {
String testInt = "hey";
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
InfoSender test = new InfoSender();
test.asd();
// script g = new script();
// mobile h = new mobile();
}
private void asd() {
new StatusGUI(this);
}
}
and I have the StatusGUI class (didn't include initComponents):
public class StatusGUI extends javax.swing.JFrame {
Class clazz;
/** Creates new form StatusGUI */
public StatusGUI(Object invokerObject) {
initComponents();
setVisible(true);
setLocationRelativeTo(null);
clazz = invokerObject.getClass();
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
try {
Field[] fields = clazz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
jTextArea1.append(fields[i].getName() + " | " + fields[i].getType() + " | " + fields[i].get(clazz));
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
On pressing the button, it would successfully write the name of the fields and the types.
When I wanted to add the value of the public fields, I quickly learned that this was not possible without declaring them static (at least not to my knowledge).
And that's despite it is okay for the field to be an instance field according to the Java Field Class documentation:
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/reflect/Field.html
The stack trace of the exception:
java.lang.IllegalArgumentException: Can not set java.lang.String field infosender.InfoSender.testInt to java.lang.Class
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:37)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:18)
at java.lang.reflect.Field.get(Field.java:358)
at infosender.StatusGUI.jButton1ActionPerformed(StatusGUI.java:93)
at infosender.StatusGUI.access$000(StatusGUI.java:22)
at infosender.StatusGUI$1.actionPerformed(StatusGUI.java:54)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6289)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6054)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4652)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4482)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
at java.awt.Container.dispatchEventImpl(Container.java:2085)
at java.awt.Window.dispatchEventImpl(Window.java:2478)
at java.awt.Component.dispatchEvent(Component.java:4482)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:644)
at java.awt.EventQueue.access$000(EventQueue.java:85)
at java.awt.EventQueue$1.run(EventQueue.java:603)
at java.awt.EventQueue$1.run(EventQueue.java:601)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
at java.awt.EventQueue$2.run(EventQueue.java:617)
at java.awt.EventQueue$2.run(EventQueue.java:615)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:614)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Appreciate any help :)
Mike.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
简而言之,问题是您正在使用 Field.get() 错误。您是说:
...其中 clazz 是您尝试从中获取字段值的对象的类。这就是为什么您只能看到静态字段。您想要做的事情是这样的:
要获取每个实例属性的值,您需要传递要从中提取值的对象的实例,而不是对象的类。
请注意,您还可以在调用
之前调用
。fields[i].setAccessible(true)
来获取private
和protected
字段的值>fields[i].get()In a nutshell, the problem is that you're using Field.get() wrong. You are saying:
...where
clazz
is the class of the Object you are trying to get the field value from. That is why you are only able to see static fields. What you want to do is something like this:To get the value of a per-instance property, you need to pass the instance of the Object that you want to extract the value from, not an instance of the Object's class.
Note that you can also get the value of
private
andprotected
fields by callingfields[i].setAccessible(true)
prior to callingfields[i].get()
.方法
Field#get(Object)
采用实际对象来提取值,而不是Class
。所以它应该是所以
invokerObject
应该设置为StatusGUI
中的一个字段,以便它可以传递到您的jButton1ActionPerformed
方法。The method
Field#get(Object)
takes the actual object to extract the value from, not theClass
. So it should beSo
invokerObject
should be set to a field inStatusGUI
so it can be passed to yourjButton1ActionPerformed
method.