try-finally的時候try裏面帶return

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

相關文章
相關標籤/搜索