get(Object obj) of field not working with instance variables
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(Even开发者_JS百科tQueue.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.
In a nutshell, the problem is that you're using Field.get() wrong. You are saying:
fields[i].get(clazz)
...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:
fields[i].get(invokerObject)
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
and protected
fields by calling fields[i].setAccessible(true)
prior to calling fields[i].get()
.
The method Field#get(Object)
takes the actual object to extract the value from, not the Class
. So it should be
fields[i].get(invokerObject)
So invokerObject
should be set to a field in StatusGUI
so it can be passed to your jButton1ActionPerformed
method.
精彩评论