日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

字節碼指令---異常處理

每個時刻正在執行的當前方法就是虛擬機棧頂的棧幀。方法的執行就對應著棧幀在虛擬機中入棧和出棧的過程。當一個方法執行完,有兩種情況,一種是正常執行,另一種是異常。

完成出口(返回地址)

正常返回:(調用程序計數器中的返回地址)

三部曲:

  1. 恢復上層方法的局部變量表和操作數棧
  2. 把返回值(如果有的話)壓入調用者棧幀的操作數棧中。
  3. 調整程序計數器的值指向方法調用指令后面的一條指令。

異常返回

通過異常處理表中的<非棧幀中的>來確定

異常機制

從字節碼了解Java語言特性

 


從字節碼了解Java語言特性

 

如果熟悉JAVA語言,那么對以上異常繼承體系一定不會陌生。其中Error和RuntimeException是非檢查型異常,也就是不需要去catch或throw的異常。

異常表

從字節碼了解Java語言特性

 


從字節碼了解Java語言特性

 

在synchronized生成的字節碼中,其中包含了兩條monitorexit指令,是為了保證所有的異常條件都能夠退出。可以看到,編譯后的字節碼,都帶有一個叫Exception table的異常表,里面每一行數據,都是一個異常處理器。

  1. from指定字節碼索引的開始位置。
  2. To指定字節碼索引的結束位置。
  3. Target異常處理的起始位置。
  4. Type異常類型

也就是說,只要from,to之間出現了異常,就會跳轉到target所指定的位置。

我們看到第一條monitorexit(16)(monitorenter和monitorexit兩條指令來支持synchronized關鍵字的語義)在異常表第一條(7-17)的范圍內。如果異常則調到20行。第二個monitorexit同理。

Finally---IOException

通常我們在做一些文件讀取的時候,都會在finally代碼塊中關閉流,以避免內存溢出。關于這個場景,我們再分析一下下面這段代碼的異常表

從字節碼了解Java語言特性

 

上面的代碼,捕獲了一個FileNotFoundException異常,然后再finally中捕獲了一個IOException異常。當我們分析字節碼的時候,卻發現了一個有意思的地方,IOException足足出現了三次。

從字節碼了解Java語言特性

 

Java編譯器使用了一種比傻的方式來組織finally的字節碼。它分別在try,catch的正常執行路徑上,復制了一份finally代碼。追加在正常執行的后面。同時,再復制一份到其他異常執行邏輯出口處。(相當于對于字節碼來說,如果異常中有finally的異常表。那么它會把自己的異常在try中,catch中各復制一份。怪不得finally一定能走到。有段時間還以為finally是異步達到的必然執行的效果)。

不報錯的除以0

從字節碼了解Java語言特性

 


從字節碼了解Java語言特性

 

從字節碼可知,0-7行出問題直接走到第9行,也就是finally中。永遠不會執行第8行的ireturn。

字節碼指令---裝箱拆箱

Java中有8種基本數據類型,但是鑒于Java的面線對象特點,它們同樣有著對應的8個包裝類型。比如int和integer,包裝類型的值可以為null(基本類型沒有null值)。而數據庫普遍存在null值,所有實體類中所有屬性應采用包裝類型,很多時候,它們都可以相互賦值。

從字節碼了解Java語言特性

 


從字節碼了解Java語言特性

 

通過觀察字節碼,我們發現

  1. 在進行乘法運算的時候,調用了Integer.intValue方法來獲取基本類型的值。
  2. 賦值操作使用的是Integer.valueOf方法。
  3. 在方法返回的時候,再次使用了Integer.valueOf方法對結果進行了包裝。

這就是Java中的自動裝箱拆箱的底層實現。

IntegerCache

查看valueOf源碼。發現low和high之間還有一個cache靜態變量

從字節碼了解Java語言特性

 

繼續追蹤

從字節碼了解Java語言特性

 

發現一般緩存是-128~127.最小值是寫死的,但是最大值可以通過-XX:AutoBoxCacheMax來修改上限。

那么下面一道經典面試題會輸出什么結果呢?

從字節碼了解Java語言特性

 

一般不修改參數的情況下就是true,false。

字節碼指令----數組

其實,數組是JVM內置的一種對象類型。這個對象同樣繼承了Object類。可以用代碼解釋。

從字節碼了解Java語言特性

 


從字節碼了解Java語言特性

 

數組創建

可以看到,新建數組的代碼,被編譯成了newarray指令。(每當遇見new指令后,都會跟一個dup指令)。

從字節碼了解Java語言特性

 


從字節碼了解Java語言特性

 


從字節碼了解Java語言特性

 

具體操作:

4. iconst_0,數組下標為0的常量壓入操作數棧中

5. Sipush,將一個常量為1111的值壓入操作數棧中

8. Iastore,將這個int型變量數組索引為0的位置中

為了支持多種類型的字面量能夠壓入數組,提供了bastore,castore,sastore,iastore等等。

數組訪問

從字節碼了解Java語言特性

 

數組的訪問:28~30行實現

從字節碼了解Java語言特性

 

  1. aload_1:該方法的局部變量表中索引為1的引用推送至操作數棧。此處是生成的arr數組引用(意思整個數組先丟到操作數棧里)。
  2. Iconset_2:將int為2的數字推送至操作數棧
  3. aload:在數組中取出索引為2的數推送到操作數棧。

獲取數組長度

從字節碼了解Java語言特性

 


從字節碼了解Java語言特性

 

獲取數組長度指令 arraylength

字節碼指令--foreach

無論是java數組還是List,都可以使用foreach語句進行遍歷。雖然在語言層面它們的表現形式是一致的。但是實際的方法并不同。

從字節碼了解Java語言特性

 

數組:將它們代碼解釋成了傳統的變量方式,即:for(int i;i<length;i++)的形式。

List實際是把List對象進行迭代并遍歷,在循環中,使用了Iterator.next()的方法。

使用jd-gui等反編譯工具,可以看到實際代碼的效果

從字節碼了解Java語言特性

 

字節碼指令總結

Java的特性非常多,這里不一一列出。但是可以通過查看字節碼的方式,從字節碼的角度分析它的原理,一窺究竟。

本次總結輸入拋磚引玉,給大家一個學習思路。

比如異常處理,finally塊的執行順序,以及隱藏的裝箱拆箱和foreach語法糖的底層實現。

還有字節碼指令。可能幾千行,看起來很嚇人,但是執行速度都是納秒級的。Java的無數框架,包括JDK,也不會為了優化這些行數,就去增加一次Java線程的上下文切換,這個比幾千行字節碼執行慢得多。

分享到:
標簽:語言 Java
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定