解释执行 不等于 编译
现代JVM在执行Java代码的时候,通常都会将解释执行与编译执行二者结合起来进行.
- 所谓解释执行,就是通过解释器来读取字节码,遇到相应的指令就去执行该指令
- 所谓编译执行,就是通过即时编译器(Just in Time, JIT)将字节码转换为本地机器码来执行;现代 JVM 会根据代码热点来生成相应的本地机器码
基于栈的指令集和基于寄存器的指令集的关系
- JVM 执行指令时所采取的方式是基于栈的指令集
- 基于栈的指令集主要有入栈和出栈两种;
- 基手栈的指令集的优势在于它可以在不同平台之间移植,而基于寄存器的指令集是与硬件架构累密关联的,无法做到可移植。
- 基于栈的指令集的缺点在于完成相同的操作,指令集通常要比基于寄存器的指令集要多;基于栈的指令集是在内存中完成操作的,而基于寄存器的指令集是直接由 CPU 来执行的,是在高速缓冲区中进行的,速度要快很多。虽然虚拟机可以采用一些优化手段,但总体来说,基于栈的指令集的执行速度要慢一些;
2 - 1
1. iconst_1 1 压到栈顶
2. iconst_2 2 压到栈顶
3. isub 3 栈弹出两个数,并做减法, 2 - 1, 结果再压入到栈里
4. istore_0 4 将栈顶的元素放到局部变量表的第 0 个 slot 中
透过字节码审视 java 动态代理的运作机制
spring aop 中会生成代理类,代理真正目标的 bean,
spring 采取两种手段实现
- 采用如 cglib 字节码库,在运行期动态根据我们所指定的类型生成相应的 class
- 基于 java 的动态代理,只能对接口进行代理,不能对一个具体的类进行代理,spring一般都会面向接口编程,只要使用了接口,spring 都会采用动态代理的方式为我们的目标类生成相应的代理类
动态代理的好处之一是真实对象尚不存在的情况下,我们就可以将动态代理对象提前创建出来,使得他的逻辑可以面对很多种情况。
Proxy.newProxyInstance:一次性生成代理类($Proxy0)的实例,父类是 Proxy
两步操作:1. 动态生成代理类本身; 2. 再去生成代理类的实例
equals(), hashcode(), toString() 会带代理类中重写(super.h.invoke()) blog.csdn.net/weixin_3840…