2016-03-21 4 views
-2

Ich habe gerade den folgenden minimalistischen Testfall:Was ist falsch an meinem Aufruf von Method.invoke?

package testcase; 

public class Main 
{ 

    public static void main(String[] args) 
     throws Throwable 
    { 
     if (args.length == 0) 
      Main.class.getMethod("main", String[].class).invoke(null, new String[] { "test" }); 
    } 

} 

Es sollte nur laufen, ohne Ausgang und keine Ausnahme. Die Methode main sollte sich selbst über Reflektion aufrufen. Jedoch habe ich die folgende Ausnahme erhalten:

Exception in thread "main" java.lang.IllegalArgumentException: argument type mismatch 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at testcase.Main.main(Main.java:10) 

Und ich kann nicht herausfinden, warum ...

+0

Wenn Sie dies kompilieren, erhalten Sie eine Warnung vom Compiler, die Ihnen einen Hinweis darauf gibt, was falsch ist. – Jesper

Antwort

8

Verwenden

public static void main(String[] args) throws Throwable { 
    if (args.length == 0) 
     Main.class.getMethod("main", String[].class) 
        .invoke(null, new Object[] {new String[] { "test" }}); 
} 

Das Problem ist, dass invoke Vararg Parameter hat, die entweder Array sein könnte oder Die Liste der Objekte und Java-Arrays ist kovariant. So wird .invoke(null, new String[] { "test" }) vom Compiler genauso interpretiert wie .invoke(null, new Object[] { "test" }). Sie sollten Compiler-Warnung über diese Mehrdeutigkeit haben.

+3

mit 'invoke (null, (Object) (new String [] {" test "})) sollte auch funktionieren, AFAIK. –

0

Besetzung new String[] { "test" } in einem new Object[] {}.