转自:https://blog.csdn.net/wy_05689/article/details/123101320
Java反射性能为什么差?
性能差是相对的,是相对于我们直接调用。
直接调用的时候,是静态的 ,实例类型,方法名,参数类型这些都是明确的,编译阶段已经处理了权限,方法可见性,参数类型等校验,之后jvm加载解析的时候已经将方法的符号引用转为地址引用了,到我们执行方法的时候,就可以直接新建栈帧进行方法调用了。
那么反射的时候就不一样了,反射是动态的,在运行的过程中才知道我们要调用什么类的什么方法,在执行的时候才明确下来,但是你那些编译阶段的校验以及一些安全机制的操作 仍然 是不能少的,所以你在执行的时候依然要做校验等安全机制的操作,所以反射性能慢。另外,它是动态的,所以可能会存在一些jvm无法优化的因素。
分析完java反射的过程以及概述了反射性能慢的原因,下面进行下原因总结:
3.1. 获取Method对象慢:a. 需要检查方法权限; b. 需要遍历筛选寻找方法,甚至还要遍历父类的方法或者接口; c, 每一个Method都有一个root,不暴露给外部,而是每次copy一Method。
3.2 调用invoke方法慢: a. invoke调用方法需要对参数做封装和解封装等操作(啥意思?invoke参数是Object,那我传int, long等基本类型的参数,它里面是不是要做封装和拆封的操作?会不会产生大量的对象?);b. 调用的时候还要检查方法的权限,还要校验参数;c, invoke调用逻辑是委托给MethodAccessor的,而这个MethodAccessor对象实懒加载,你第一次调用invoke的时候才创建。
3.3. 因为是动态加载的,vm无法做优化。