登录  /  注册
java 8里 Method方法bug
高洛峰
高洛峰 2016-10-26 16:41:24
[Java讨论组]

在写rpc框架的时候出现了头疼问题:

public Object invoke(Object bean)throws Exception {
        Method[] methods = clazz.getMethods();
        for (Method method:methods) {
            if(method.getName().equals(method.getName())){
                return method.invoke(bean, param);
            }
        }
        throw new Exception("找不到方法");
    }

这样写能找到方法,没有问题!!但是换成下面的方式就出问题了。

public Object invoke(Object bean)throws Exception {
        return clazz.getMethod(method, param.getClass()).invoke(bean, param);
    }

跑出异常为:java.lang.NoSuchMethodException:com.robin.interf.UserService.getUser(java.lang.Integer)

java使用的版本是:jdk1.8.0_101

Class.java代码跟踪:

1.png

是一个searchMethods的方法在查找,继续走

1.png

代码走到这里,res=null,导致NoSuchMethodException异常,算是java8 bug吧!

原因:searchMethods方法里,m.getName() == internedName这句导致的,正确的是m.getName().intern() == internedName,因为m.getName()是堆里取出值,而internedName是常量池里的,而m.getName().intern()会将常量池里存在的字符串直接取到,不存在的会放入到常量池里。

建议:建议使用class.getMethods(),然后我们自己遍历,不推荐使用class.getMethod(methodName, paras)


高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全部回复(1)
三叔

你的逻辑只匹配了方法名称并没有匹配参数类型吧。

public Object invoke(Object bean)throws Exception {
    Method[] methods = clazz.getMethods();
    for (Method method:methods) {
        if(method.getName().equals(method.getName())){
            return method.invoke(bean, param);
        }
    }
    throw new Exception("找不到方法");
}

上面的代码是楼主查询的method的方式吧,我说未匹配类型,是指楼主自己写的代码中没有匹配参数的类型。而jdk内部是有这个判断的。

public class Test {    public String hello(int i) {        return "Hello" + i;
    }    public static void main(String[] args) {
        Test t = new Test();        try {
            Method m = Test.class.getMethod("hello", Integer.class);
            System.out.println(m.invoke(t, 9));
        } catch (Exception e) {
            e.printStackTrace();
        }        try {
            Method m = Test.class.getMethod("hello", int.class);
            System.out.println(m.invoke(t, 8));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

我不太清楚楼主的代码是如何编写的,不过这段代码楼主可以运行一下看看区别。


热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2024 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号