2015-09-03 1 views
7

Я должен пропустить что-то очень фундаментальное. Когда я пытаюсь передать массив любого типа во время вызова метода, я получаю сообщение об ошибке. Однако, когда я делаю это нормально, он работает.IllegalArgumentException при передаче массива в качестве параметра во время вызова метода

Это полный код, который не удается

import java.lang.reflect.Method; 

public class Main { 
    public static void main(String[] args) throws Exception { 

     // Normal 
     MyClass.sayHello(new String[] {"StackOverflow"}); 

     // Reflection 
     Method m = MyClass.class.getMethod("sayHello", String[].class); 
     m.invoke(null, new String[]{"StackOverflow"}); 
    } 

    static class MyClass { 
     public static void sayHello(String[] args) { 
      System.out.println("Hello " + args[0]); 
     } 
    } 
} 

Исключение брошено

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:497) 
at Main.main(Main.java:11) 

String... не работает, либо кстати.

ответ

7

Проблема заключается в том, что второй параметр для invoke предназначен для массива аргументов - вы указываете только один аргумент.

В большинстве случаев это было бы нормально, так как второй параметр Method.invoke является параметром varargs, но поскольку ваш аргумент уже является массивом, совместимым с Object[], компилятор не создает массив-оболочку. Я ожидаю, что вы получите время компиляции предупреждения, как это:

Main.java:11: warning: non-varargs call of varargs method with inexact argument type for 
         last parameter; 
     m.invoke(null, new String[]{"StackOverflow"}); 
        ^
    cast to Object for a varargs call 
    cast to Object[] for a non-varargs call and to suppress this warning 

Вы можете либо явно создать массив оберточной аргумент, или бросить аргумент Object так что компилятор должен обернуть его себе:

// Creates the wrapper array explicitly 
m.invoke(null, new Object[] { new String[] { "StackOverflow" } }); 

или

// Compiler creates the wrapper array because the argument type is just Object 
m.invoke(null, (Object) new String[] { "StackOverflow" }); 
+0

TLDR: Как всегда RTFD – mvd

+0

Да, я получил такое же предупреждение. Не имеет никакого смысла, почему Java понадобится массив аргументов массива, но он работает. Благодаря! – TomTom

+0

@TomTom: Он имеет прекрасный смысл: ему нужен массив, потому что может быть несколько аргументов. Единственный элемент этого массива сам по себе является массивом, потому что параметром метода является массив. Попробуйте добавить еще один параметр в метод, и это будет иметь больше смысла. И в будущем, * никогда * игнорировать предупреждения :) –

Смежные вопросы