使用可变形参过程中,整数自动装箱转换成了Integer类型,导致反射过程中错误如何解决

使用可变形参过程中,整数自动装箱转换成了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,所以就找不到对应的方法;

img

所以:

img

在代码里加if判断,如果是包装类型则替换为基本类型。