反射
简单例子:
1 | try { |
Java反射效率低的主要原因(结论):
- Method#invoke方法会对参数做封装和解封操作
- 需要检查方法可见性
- 需要校验参数
- 反射方法难以内联
- JIT无法优化
Java反射原理–获取要反射的方法
反射的使用
例子
1 | public class RefTest{ |
获取反射方法时有俩方法,
getMethod
和getDeclaredMethod
getMethod / getDeclaredMethod
先整体看下 getMethod/getDeclaredMethod
的实现
1 | class Class { |
俩方法有两个区别:
checkMemberAccess
传入的参数不一样
1 | interface Member{ |
即PUBLIC
会包含所有的public
方法,包括父类的方法。DECLARED
会包括所有自己定义的方法,public
、protected
、private
都在此,不包括父类的方法。
- 获取方法不同,
getMethod
调用getMethod0
,getDeclaredMethod
调用privateGetDeclaredMethods
1 | //获取自身定义的方法,参数 publicOnly表示是否只获取公共方法 |
getMethod0
会递归查找父类方法,其中会调用到privateGetDeclaredMethods
方法
getMethod
getMethod方法流程图
checkMemberAccess
1 | class Class{ |
getMethod0
1 | class Class{ |
getMethodsRecursive
1 | class Class{ |
我们平时编写Java代码时,同一个类是不能有方法名和方法参数都相同的方法的,在JVM中一个方法签名是和返回值、方法名、方法参数三者相关的。也就是说,在JVM中可以存在方法名和方法参数都相同但是返回值不同的方法。
sun.misc.Unsafe
例子:获取对象地址
1 | import java.lang.reflect.Field; |
深入理解sun.misc.Unsafe原理
Unsafe类中的核心方法
1 | //重新分配内存 |