简体   繁体   中英

Java invoke its own private method with fix parameter

Before, I have a Swing class that have many if-else statements. after removing all if-else by using java reflection, i can invoke its own method successfully. However, i still cant pass a parameter into the method. How to make the code below works with passing ActionEvent parameter?

public void actionPerformed(ActionEvent e) {
    try {
        //Method method = this.getClass().getDeclaredMethod(e.getActionCommand());
        Method method = this.getClass().getMethod(e.getActionCommand() );
        method.invoke(this);                
    } catch (IllegalArgumentException e1) {
        e1.printStackTrace();
    } catch (IllegalAccessException e1) {
        e1.printStackTrace();
    } catch (InvocationTargetException e1) {
        e1.printStackTrace();
    } catch (SecurityException e1) {
        e1.printStackTrace();
    } catch (NoSuchMethodException e1) {
        e1.printStackTrace();
    }
}
public void generate(ActionEvent e){
    System.out.println("Generating");
}

Simply pass the argument(s) as additional arguments to Method.invoke() :

method.invoke(this, e);

This

Method method = this.getClass().getMethod(e.getActionCommand() );

reflects a method with no arguments (assuming, e.getActionCommand() reference the method name "generate" ). It will reflect the method generate() but you want to reflect generate(ActionEvent e) , which simply is a different method (hint: overloading)

You'll have to reflect

Method method = this.getClass().getMethod(e.getActionCommand(), ActionEvent.class);

and then do a

method.invoke(this, e);

You need to change two methods, one to find a method which takes an ActionEevent and the second to pass the event.

try {
   Method method = getClass().getMethod(e.getActionCommand(), ActionEvent.class);
   method.invoke(this, e);  
} catch (Exception e) {
   // log the 'e' exception
}

Class.getMethod() only finds public methods. You need Class.getDeclaredmethod() .

Also, you'll need to look for the argument type:

Method method = getClass().getDeclaredMethod(e.getActionCommand(), ActionEvent.class);

I'd prefer to do it with a helper method like this:

public static Method findMethodByNameAndArgs(final Class<?> clazz,
    final String name, final Object... args) {
    for (final Method method : clazz.getDeclaredMethods()) {
        if (method.getName().equals(name)) {
            final Class<?>[] parameterTypes = method.getParameterTypes();
            if (parameterTypes.length == args.length) {
                boolean matchArgs = true;
                for (int i = 0; i < args.length; i++) {
                    final Object param = args[i];
                    if (param != null && !parameterTypes[i].isInstance(param)) {
                        matchArgs = false;
                        break;
                    }
                }
                if (matchArgs) return method;
            }
        }
    }
    throw new IllegalArgumentException(
        "Found no method for name '" + name + "' and params " 
       + Arrays.toString(args));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM