2013-04-11 13 views
8

Próbuję napisać metodę, która wykonuje statyczną metodę z innej klasy, przekazując tablicę łańcuchów jako argumenty metody.Wywołanie metody z parametrem tablicy przy użyciu refleksji

Oto co mam:

public static void 
executeStaticCommand(final String[] command, Class<?> provider) 
{ 
    Method[] validMethods = provider.getMethods(); 

    String javaCommand = TextFormat.toCamelCase(command[0]); 

    for (Method method : validMethods) { 
     if (method.getName().equals(javaCommand)) { 
      try { 
       method.invoke(null, new Object[] { new Object[] { command } }); 
      } catch (IllegalAccessException e) { 
       e.printStackTrace(); 
      } catch (InvocationTargetException e) { 
       Throwable ex = e.getCause(); 
       ex.printStackTrace(); 
      } 
      break; 
     } 
    } 
} 

taka, że:

String[] args = new String[] { "methodName", "arg1", "arg2" }; 
executeStaticCommand(args, ClassName.class); 

powinien wykonać to:

public class ClassName { 
    public static void methodName(String[] args) { 
     assert args[1].equals("arg1"); 
    } 
} 

Jednak Dostaję IllegalArgumentException s.

Odpowiedz

9

mieć dwa problemy:

  1. Parametr typu docelowego jest String[], ale jesteś przejazdem w Object[]
  2. Przekazujesz całą tablicę poleceń jako argumenty, która zawiera nazwę metody

Problemy występują w wewnętrznym bloku try, więc pokazuję tylko ten kod.

String[] args = Arrays.copyOfRange(command, 1, command.length - 1); 
method.invoke(null, new Object[]{args}); // must prevent expansion into varargs 

Dzięki Perception za przypomnienie mi o numerze varargs

+1

Właśnie pisał, plus jeden dodatkowy dodatek, który może zrobić. Aby to zadziałało, musisz zmienić wywołanie na 'method.invoke (null, new Object [] {args})). – Perception

+0

@Perception, ale parametr metody docelowej to 'String []', a nie 'String, String'. Czy to nie działa (nie mam tutaj edytora Java)? – Bohemian

+1

Nie działa, ponieważ tablica zostaje rozwinięta do varargs, powodując niezgodność typów sygnatur i argumentów. – Perception

0

Metoda, którą próbujesz wywołać, oczekuje tablicy typu String, ale przekazujesz tablicę Object jako parametr. Zmień go na String array Lub możesz przekazać dowolny typ, jeśli metoda oczekuje Object.

method.invoke (polecenie null, (Object));

+0

Gdy używam '(Object) command', jeśli' command.length' wynosi 1, metoda jest poprawnie nazywa, jeśli jest nieco ' > 1', żadna metoda nie jest wywoływana. – azz

0

podstawie this question, wygląda na to wezwanie powinno być

method.invoke(null, command); 
Powiązane problemy