使用可变形参过程中,整数自动装箱转换成了Integer类型,导致反射过程中错误如何解决?
public class FrameTest {
public static void main(String[] args) {
invoke("hello","charAt",3);
}
public static void invoke(Object obj, String methodName, Object ... params) {
Method method = null;
Class[] clas = new Class[params.length];
for (int i = 0; i < params.length; i++) {
clas[i] = params[i].getClass();
}
try {
method = obj.getClass().getMethod(methodName,clas);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
method.invoke(obj,params);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
java.lang.NoSuchMethodException: java.lang.String.charAt(java.lang.Integer)
我知道哪里出了问题,但是必须使用可变形参,无法避免自动装箱
正确调用方法
首先题主的目的很明显,就是利用一个可变参数,实现 invoke 和 getMethod 中各自需要的可变参数 (Class<?>)parameterTypes 和 (Object)args。题主需要注意:两者的类型不同,而 getMthod 阶段中的 parameterTypes 必须是 int.class 或 其他类型.class,经测试.getClass 是无法通过getMethod 这一步,也就无法获取该方法的示例,因此,下面的invoke也就必然空指针。所以楼主尽可能在调用 invoke 之前,想办法解决获取该类型的.class问题,就可以解决问题。也就是说:getMethod 中的可变参数是一个Class 数组,而数组中的元素都是 类型.class,而不是 类型.getClass。你可以自己 Debug看一下。
或者你可以这么干
public static void invoke(Object obj, String methodName, Object ... params) throws ClassNotFoundException {
Method method = null;
Class<?>[] args = null;
Method[] declaredMethods = obj.getClass().getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
if(declaredMethod.getName().equals(methodName)) {
args = declaredMethod.getParameterTypes();
break;
}
}
try {
method = obj.getClass().getMethod(methodName,args);
method.invoke(obj,params);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
你的所谓整数,到底是个什么类型呢,整数不是类型的概念呀
你想调用 "hello".charAt(3) ;
但是反射去寻找方法时,参数类型需要是int,给的又是int自动包装后的Integer,所以就找不到对应的方法;
所以:
在代码里加if判断,如果是包装类型则替换为基本类型。