如何解决以字符串数组为参数的调用方法会导致IllegalArgumentException
我正在使用运行时反射来加载包含以下两个方法的类:
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
具有以下签名:
public Object invoke(Object obj,Object... args)
args
是一个可变参数,允许您将调用的方法的每个参数作为invoke
的参数进行传递,例如
someStaticMethod.invoke(null,param1,param2,param3);
将致电:
someStaticMethod(param1,param3);
另一方面,args
的类型实际上只是Object[]
,并且由于数组是协变的,因此存在从String[]
到Object[]
的转换。>
因此,当您将String[]
中的strArr
传递给invoke
时,可能会发生以下两种情况之一:
-
strArr
被转换为Object[]
,并且每个String
被视为要调用的方法的参数。 - 整个
strArr
被视为要调用的方法的参数之一,就像非数组类型一样。
编译器恰好偏爱第一个(请参见here。请注意,可变域调用的优先级最低),因此实际上是在传递参数"1"
,{{1} },"2"
,而不是一个单个"3"
。
另一方面,String[]
不能直接转换为int[]
,因为Object[]
是原始的,因此编译器只能选择上面的第二个选项。
强制第二个选项的一种方法是强制转换为int
:
Object
另一种方法是创建另一个用clazz.getMethod("bar",String[].class).invoke(null,(Object)strArr);
包装的Object[]
:
String[]
,
您必须将将要执行该方法的初始化对象作为invoke()方法的第一个参数传递。
Foo foo =新的Foo(); 方法method = clazz.getMethod(“ method”);
method.invoke(foo,params []);
invoke()需要对象执行该方法。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。