2015-09-03 16 views
7

Tôi phải bỏ lỡ điều gì đó rất cơ bản. Khi tôi cố gắng để vượt qua một mảng của bất kỳ loại nào trong một lời gọi phương thức tôi nhận được một lỗi. Tuy nhiên khi tôi làm điều đó bình thường nó hoạt động.IllegalArgumentException khi truyền một Mảng làm tham số trong khi gọi phương thức

Đây là mã hoàn chỉnh mà không

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

Các ngoại lệ ném

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... không hoạt động hoặc btw.

Trả lời

7

Vấn đề là tham số thứ hai là invoke có nghĩa là một mảng đối số - bạn chỉ xác định một đối số duy nhất.

Trong hầu hết các trường hợp, thông số thứ hai là Method.invoke là tham số varargs, nhưng đối số của bạn đã là một mảng tương thích với Object[], trình biên dịch không tạo mảng bao bọc. Tôi mong đợi bạn để có được một thời gian biên dịch cảnh báo như thế này:

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 

Bạn có thể có thể tạo ra một cách rõ ràng một mảng gói các đối số, hoặc đúc lập luận để Object để trình biên dịch cần phải quấn nó bản thân:

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

hoặc

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

TLDR: Như mọi khi RTFD – mvd

+0

Vâng, tôi đã cảnh báo tương tự. Nó không có ý nghĩa gì vì sao Java sẽ cần một mảng các đối số mảng, nhưng nó hoạt động. Cảm ơn! – TomTom

+0

@TomTom: Nó có ý nghĩa hoàn hảo: nó cần một mảng vì có thể có nhiều đối số. Phần tử duy nhất của mảng đó là chính nó là một mảng, bởi vì tham số cho phương thức là một mảng. Hãy thử thêm một tham số khác vào phương thức và nó sẽ có ý nghĩa hơn. Và trong tương lai, * không bao giờ * bỏ qua cảnh báo :) –

Các vấn đề liên quan