我们通常使用java反射很简单,直接使用method.invoke(obj,params)即可,但是当我们面对方法的入参为数组时会有问题,会报错:Exception in thread “main” java.lang.IllegalArgumentException: wrong number of arguments,字面意思是参数数量不正确,但是你反复检查也看不出怎么就数据量正确了,其实原因是这样的:
JDK在1.5版本之前,Java没有可变参数这种东西,多个不定数量的参数使用数组来传递,1.5版本之后才加入了可变参数这个功能,这样一来,以前的程序就会运行错误,出现不兼容问题。为了跟1.5以前的程序兼容,一个方法中接受可变参数的地方,如果传入数组,就会自动分解为多个参数。
比如你的方法的入参为String[] args,然后你反射调用时传入new String[]{“a”,“b”} ,然后就会被分解成"a","b"两个字符串参数,而你的方法入参其实只有个Stirng[]参数,所以就会有前面的报错wrong number of arguments,知道原因我们该怎么解决呢?
-
既然数组会被分解,那我们就不传数组传一个对象,即(Object) new String[]{“a”,“b”},把数组转换成一个Object对象。
-
既然他会分解,那我就包两层,即new Object[]{new String[]{“a”,“b”}},这样他会把外面的一层Object分解,分解后变成了new String[]{“a”,“b”},就满足条件了,具体代码如下:
我们通常使用java反射很简单,直接使用method.invoke(obj,params)即可,但是当我们面对方法的入参为数组时会有问题,会报错:Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments,字面意思是参数数量不正确,但是你反复检查也看不出怎么就数据量正确了,其实原因是这样的:
JDK在1.5版本之前,Java没有可变参数这种东西,多个不定数量的参数使用数组来传递,1.5版本之后才加入了可变参数这个功能,这样一来,以前的程序就会运行错误,出现不兼容问题。为了跟1.5以前的程序兼容,一个方法中接受可变参数的地方,如果传入数组,就会自动分解为多个参数。
比如你的方法的入参为String[] args,然后你反射调用时传入new String[]{"a","b"} ,然后就会被分解成"a","b"两个字符串参数,而你的方法入参其实只有个Stirng[]参数,所以就会有前面的报错wrong number of arguments,知道原因我们该怎么解决呢?
(1)、既然数组会被分解,那我们就不传数组传一个对象,即(Object) new String[]{"a","b"},把数组转换成一个Object对象。
(2)、既然他会分解,那我就包两层,即new Object[]{new String[]{"a","b"}},这样他会把外面的一层Object分解,分解后变成了new String[]{"a","b"},就满足条件了,具体代码如下:
public class ReflectQuestion {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
ReflectQuestion reflectQuestion = ReflectQuestion.class.newInstance();
Method method = ReflectQuestion.class.getDeclaredMethod("test",String[].class);
//错误
method.invoke(reflectQuestion,new String[]{"aa","bb"});
//正确
method.invoke(reflectQuestion,(Object)new String[]{"aa","bb"});
//正确
method.invoke(reflectQuestion,new Object[]{new String[]{"aa","bb"}});
}
public void test(String[] args){
if(args!=null){
for(String arg:args){
System.out.println("args="+arg);
}
}
}
}