2014-10-03 2 views
0

Я использую отражение java для вызова API из .class. Я вижу, что моя функция - список функций, перечисленных API .getMethods(). Версия no param отлично работает, но параметризованная версия терпит неудачу.java reflection вызов функции

время вызова компиляции для API был

public static class CapabilitiesEditor extends ComboBoxPropertyEditor { 
    public CapabilitiesEditor() { 
     super(); 
     print(); // Call to print if fine . 
     setAvailableValues(new String[] { "High", "Medium", "Low", "None", }); // I want call this one . Fails 
     Icon[] icons = new Icon[4]; 
     Arrays.fill(icons, UIManager.getIcon("Tree.openIcon")); 
     setAvailableIcons(icons); 
    } 

Вот мой код, который пытается динамически изменять setAvailableValues.

Class<?> cls; 
    // Paremeterized call 
    Class[] paramObject = new Class[1]; 
    paramObject[0] = Object[].class; // Function takes a single parameter of type Object[] 
    Object[] params = new String[] { "H", "M", "L", "N" }; 

    // no paramater version 
    Class noparams[] = {}; 

    try { 

    cls = Class.forName("com.app.services.prop.system.SystemTopologyBean$CapabilitiesEditor");         Object obj = cls.newInstance(); 

    for(Method method : cls.getMethods()){ 
     System.out.println("method = " + method.getName()); 
    } 
    // WORKS 
    Method method = cls.getDeclaredMethod("print", noparams); 
    method.invoke(obj, null); 

    // **DOES NOT WORK** 
    Method method = cls.getDeclaredMethod("setAvailableValues", paramObject); 
    method.invoke(obj, params); 

    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException e2) { 
           // TODO Auto-generated catch block 
           e2.printStackTrace(); 
          } 

Я всегда получаю следующее исключение

java.lang.NoSuchMethodException: com.app.services.prop.system.SystemTopologyBean$CapabilitiesEditor.setAvailableValues([Ljava.lang.Object;) 

EDIT:

Я следую за Mkyong замечательный учебник по отражению How To Use Reflection To Call Java Method At Runtime

ответ

1

Чтобы получить свой метод, а затем вызвать его, вы» необходимо сделать это следующим образом:

Class cls = Class.forName("com.app.services.prop.system.SystemTopologyBean$CapabilitiesEditor"); 
Object obj = cls.newInstance(); 
Method method = cls.getDeclaredMethod("setAvailableValues", new Class[] {String[].class}); 
method.invoke(obj, new Object[] {new String[] {"Foo", "Bar"}}); 
0

Так что здесь было две проблемы, которые мешали мне получить доступ к функции. Будьте осторожны, я должен был использовать getMethod вместо getDeclaredMethod

См. Using .getDeclaredMethod to get a method from a class extending another, чтобы узнать, какой из них должен быть применим.

Также будьте очень осторожны при вызове функции method.invoke, особенно второго параметра.

См. How to call MethodInvoke - reflection и ответ Майкла выше для правильного вызова.