我正在使用运行时反射来加载一个包含以下两个方法的类:
public static void foo(int[] args)
{
System.out.print("foo invoked: ");
for(int arg : args)
System.out.print(arg + " ");
System.out.println();
}
public static void bar(String[] args)
{
System.out.print("bar invoked: ");
for(String arg : args)
System.out.print(arg + " ");
System.out.println();
}
(两个方法完全相同,只是一个使用 int 数组,另一个使用字符串数组作为参数)
我尝试像这样调用这两个方法:
int[] intArr = {1,2,3};
clazz.getMethod("foo", int[].class).invoke(null, intArr);
String[] strArr = {"1","2","3"};
clazz.getMethod("bar", String[].class).invoke(null, strArr); //Exception
(这里的“clazz”是包含这两个方法的类,我已经在运行时加载了它)
第一次调用不会抛出异常并输出预期的输出结果,但第二次调用会抛出以下异常:
Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at ReflectionTests.main(ReflectionTests.java:63)
为什么会这样?
invoke(null, strArr)
是一个有效的调用,因此它的行为不允许改变。相反,在varargs之前,任何不能分配给Object[]
的参数都是无效的,因此现在将int[]
参数塞入幕后的数组中以将其作为反射方法的单个参数处理时,就没有兼容性问题了。 - Holger