最近學習的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的值暫存的操做了。