2011-07-15 83 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)); 
}