Java反射机制知识概括
Java反射机制概述
理解Class类并获取Class实例
类的加载与ClassLoader的理解
创建运行时类的对象
获取运行时类的完整结构
调用运行时类的指定结构
反射的应用:动态代理
反射优化
Java反射性能差的原因:
- 性能差是相对的,是相对于我们直接调用,直接调用的时候,是静态的(可能有人会问,什么时候静态的,就是实例类型,方法名,参数都是确定的),编译阶段编译器会做权限,可见性,参数等检验,加载阶段解析的时候,就会方法对应的符号引用转换为地址引用,到我们执行方法调用时,就可以直接新建栈帧进行方法调用了。
- 但是反射调用的过程中,是动态的,在执行的时候才明确下来,所以会存在一些验证以及一些安全机制的考虑,另外就是因为是动态的,所以可能会存在一些JVM无法优化的因素。
- 链接:Java反射性能分析及优化
Java 反射性能差主要原因是:
- 获取Method对象慢
- 需要检查方法权限
- 需要遍历筛选递归
- 每一个Method都有一个root,不暴漏给外部,而是每次copy一个Method
- 调用invoke方法慢
- Method#invoke 方法会对参数做封装和解封操作
- 需要检查方法可见性
- 需要校验参数
- invoke调用逻辑是委托给MethodAccessor的,而accessor对象会在第一次invoke的时候才创建,是一种lazy init方式
- 反射方法难以内联
- JIT 无法优化
结论:
-
如果反射调用场景很少,则不需要太过纠结,直接反射调用就行了。
-
如果对性能要求较高,且无法缓存Method对象的情况下,尽量选择AsmReflect来进行反射调用。如果可以缓存,则也可以考虑使用使用Java版 MethodAccessor,与AsmReflect差异并不是太大。