2011-07-15 42 views
1

之前,我有一个Swing类,它有很多if-else语句。在通过使用java反射删除所有if-else之后,我可以成功地调用它自己的方法。但是,我仍然不能将参数传递给方法。如何使下面的代码与传递的ActionEvent参数一起工作?Java调用自己的私有方法修复参数

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"); 
} 

回答

2

参数(S)作为附加参数简单地传递给Method.invoke()

method.invoke(this, e); 
+0

我已经试过了,我得到这个异常:java.lang.NoSuchMethodException:com.upd.ui._Summary.generate() – Reusable

+1

@Reusable:你在'getMethod()'调用和** not **对invoke()调用(只有'getMethod()'可以抛出这个)!你在标题中提到'private',但你的代码没有私有方法。 **如果你的方法实际上是'private',那么你**必须**使用'getDeclaredMethod()',因为'getMethod()'只会*查找公共方法。 –

+0

你只是帮我解答了我脑海中的另一个问题。我想将这种方法设置为私有方式,因为将这种方法暴露给其他方法肯定会对此方法公开的原因产生进一步的问题!谢谢! – Reusable

1

你需要改变两个方法,一是找出这需要一个ActionEevent和第二传递事件的方法。

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

它的工作!谢谢! 顺便说一句,这个代码将只有工作,如果我有方法声明为公共。为什么当我变成“私人”时失败? – Reusable

2

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

反映不带参数(假设,e.getActionCommand()参考方法名"generate")的方法。这将反映方法generate()但你要反映generate(ActionEvent e),这简直是一种不同的方法(提示:过载)

你必须反映

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

,然后做一个

method.invoke(this, e); 
1

Class.getMethod()只能找到公开的方法。你需要Class.getDeclaredmethod()

此外,你需要寻找的参数类型:

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

我宁愿用一个辅助方法这样做:

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)); 
}