开发者社区> 问答> 正文

java 8里 Method方法bug 报错

"

在写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代码跟踪:

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

代码走到这里,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)

" ![image.png](https://ucc.alicdn.com/pic/developer-ecology/2d8be73cc933436f877e8db633f8b56d.png)

展开
收起
因为相信,所以看见。 2020-05-26 13:56:37 970 0
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();
            }
        }
    }

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

    ######
    public static void main(String[] args) throws InvocationTargetException {
        try {
            Class<?> c = Class.forName("java.lang.StringBuilder");
            Object instance = c.newInstance();
            Method m = c.getMethod("append", String.class);
            Object o = m.invoke(instance, "Hello World");
            System.out.println(o);
        } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InstantiationException e) {
            e.printStackTrace();
        }
    }
    
    我也是jdk1.8.0_101, 完全没问题啊
    ######

    The parameterTypes parameter is an array of Class objects that identify the method's formal parameter types, in declared order. If parameterTypes is null, it is treated as if it were an empty array.
    api里面说了,如果第二个参数不传,会默认空数组,也就是找入参为空的方法,那肯定会报‘找不到方法’的错了

    " ![image.png](https://ucc.alicdn.com/pic/developer-ecology/c2d37851c1bc452caec3675bb776c7da.png)
    2020-05-27 10:08:52
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载