Java,立即数的类型强转导致反射找不到方法

2019-01-22  本文已影响0人  wizdzz

工作需要用到类方法的反射调用,网上找到这样一段代码:

public static Object invokeMethod(Object object, String methodName, Class[] parameterTypes, Object... parameters) {
        //根据 对象、方法名和对应的方法参数 通过反射 调用上面的方法获取 Method 对象
        Method method = getDeclaredMethod(object, methodName, parameterTypes);

        //抑制Java对方法进行检查,主要是针对私有方法而言
        method.setAccessible(true) ;

        try {
            if(null != method) {
                //调用object 的 method 所代表的方法,其方法的参数是 parameters
                return method.invoke(object, parameters) ;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

哎,既然后面传入了 parameters,那么 parameterTypes 直接 parameters.getClass() 就好了,何必再传;
于是稍加修改,该方法变成这个样子:

public static Object invokeMethod(Object object, String methodName, Object... parameters) {
        //根据 对象、方法名和对应的方法参数 通过反射 调用上面的方法获取 Method 对象
        Class[] parameterTypes = new Class[parameters.length];

        for(int i = 0; i < parameters.length; i++){
            parameterTypes[i] = parameters[i].getClass();
        }

        Method method = getDeclaredMethod(object, methodName, parameterTypes);

        //抑制Java对方法进行检查,主要是针对私有方法而言
        method.setAccessible(true) ;

        try {
            if(null != method) {
                //调用object 的 method 所代表的方法,其方法的参数是 parameters
                return method.invoke(object, parameters) ;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

嗯,不禁为自己的机智点赞;
于是加入工程,跑起来,哎,怎么反射找不到方法;
仔细观察,调用时的代码是 ClassReflectionUtils.invokeMethod(obj, "func", 123);
调试步进,观察 paramters,发现变成了 Integer 类型;


原来立即数会被强转为这种“高级立即数类”;
那么再测试一下:

public static void fun(Object... args){
        for(Object object : args){
            Class xx = object.getClass();
            System.out.println(xx);
        }
        return;
    }

public static void main(String[] args) {
    int m = 1;
    double n = 2.3;
    fun(m, n);
}

得到了如下输出:


嗯,看来确实会被强转,那么 invokeMethod 的 parameterTypes 参数是不可省略了,再恢复之前的 invokeMethod ,跑起来,成功了。
其实省略该参数还有一个问题,当 parameters.getClass() 为子类,而指定 method 中需要的父类时,findMethod 应该也找不到方法,这里感兴趣的读者可以自行测试一下。

上一篇 下一篇

猜你喜欢

热点阅读