使用反射调用方法时的注意事项

1,602 阅读1分钟

当使用反射调用方法的时候,如果被调用的方法的入参只有一个,且是数组的时候,传递实际参数给Method的invoke方法时,需要注意(如果有)。

以下是错误的写法:

import java.lang.reflect.Method;

public class Test {

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

        Class clz = Test.class;

        Method printArr = clz.getMethod("printArr", String[].class);

       String[] argsArr = {"hello"};
        printArr.invoke(new Test(), argsArr);
    }

    public static void printArr(String[] strArr) {
        for (String str : strArr) {
            System.out.println(str);
        }
    }

}
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 Test.main(Test.java:16)

我们看下java.lang.reflect.Method#invoke方法,方法实际参数是Object...,

public Object invoke(Object obj, Object... args)
        throws IllegalAccessException, IllegalArgumentException,
           InvocationTargetException
    {
     	// 假装有代码
    }

所以上述例子中实际传递给Test.main方法的入参是String类型,值为“hello”,和Test.main方法要求的入参类型String[],不一样,所以会抛出 “IllegalArgumentException: argument type mismatch”的异常。

正确的写法

import java.lang.reflect.Method;

public class Test {

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

        Class clz = Test.class;

        Method printArr = clz.getMethod("printArr", String[].class);

       String[] argsArr = {"hello"};
        // 看这里👇
        printArr.invoke(new Test(), new Object[]{argsArr});
    }

    public static void printArr(String[] strArr) {
        for (String str : strArr) {
            System.out.println(str);
        }
    }
}