try-finally的時候try裏面帶return

 最近學習的JVM小冊中老師提了個問題:

  最開始我覺得是1,結果程序跑出來是0,感到很疑惑,於是查看了下字節碼:

  

  從字節碼可以看出:

  0:定義變量0

  1:將0存入本地變量表slot-0

  2:加載slot-0到操作數棧

  3:將棧頂元素存入本地變量表slot-1

  4:對slot-0自增

  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的值暫存的操作了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章