开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜