最近学习的JVM小册中老师提了个问题:html
最开始我以为是1,结果程序跑出来是0,感到很疑惑,因而查看了下字节码:java
从字节码能够看出:oracle
0:定义变量0jvm
1:将0存入本地变量表slot-0学习
2:加载slot-0到操做数栈htm
3:将栈顶元素存入本地变量表slot-1blog
4:对slot-0自增get
7-8:加载slot-1到操做数栈并返回虚拟机
能够看到,最终返回的是slot-1的值,而自增的是slot-0的值,因此最终仍是返回的0编译
可是为何JVM要这么作的缘由的仍是不太清楚,看了Java虚拟机规范上面写的:
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.10.2.5
规范这里也说的是若是try里面有return,那么编译的时候会先把try的返回值存入到本地变量表中。看到这里我有了一些猜想:
try-finally的原理是编译的时候在return以前插入了jsr指令,执行该指令会跳到finally block,finally block这个时候被编译成了一个subroutine(子程序),
也就是一个方法,那么为了当从subroutine跳转出来的时候可以继续返回原来要返回的值,因此在执行finally block以前会先把try的返回值存入本地变量表中一个新的slot,而在finally
当中若是有操做try的返回值这个变量的时候,实际操做的是该值本来所在的slot,,说的有点绕,不太好理解,望见谅。
老师在群里发了个javac编译的代码,这个比较清楚:
因此大体能够总结为:当try有return的时候,finally里面对try的返回值的操做不起做用。咱们也能够将程序改一下:
当try里面没有return的时候,则返回1。在看看此时的字节码:
这个时候,就没有将return的值暂存的操做了。