Что не так с моим вызовом 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" } );
    }

}

Он должен просто работать без вывода и без исключения. main Метод должен вызывать себя, используя отражение. Однако я получаю следующее исключение:

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)

И я не могу понять, почему...

2 ответа

Решение

Использование

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

Проблема в том, что invoke имеет параметр vararg, который может быть либо массивом, либо простым списком объектов, а массивы Java ковариантны. Так .invoke(null, new String[] { "test" }) интерпретируется компилятором так же, как .invoke(null, new Object[] { "test" }), Вы должны иметь предупреждение компилятора об этой неоднозначности.

В ролях new String[] { "test" } в new Object[] {},

Другие вопросы по тегам