亚洲综合在线一区二区三区-日韩超碰人人爽人人做人人添-麻豆国产精品久久人妻-无码人妻丰满熟妇啪啪-天堂精品一区二区三区-99久久综合狠狠综合久久aⅴ

×
新網 > 虛擬主機 > 正文

深入理解Java之java虛擬機干凈利落的規范總結 下

  • 作者:新網
  • 來源:新網
  • 瀏覽:100
  • 2018-05-03 17:56:15

要去正確地實現一臺Java虛擬機,就需要正確地讀取class文件中每一條字節碼指令并且能正確執行這些指令所蘊含的操作即可。

  t0132608ea0fedf6d64.png

<div>        要去正確地實現一臺Java虛擬機,就需要正確地讀取class文件中每一條字節碼指令并且能正確執行這些指令所蘊含的操作即可。
  由Java虛擬機執行的每個方法都會配有零到多個異常處理器。異常處理器描述了其在方法代碼中的有效作用范圍(通過字節碼偏移量范圍來描述)、能處理的異常類型以及處理異常的代碼所在的位置。要判斷某個異常處理器是否可以處理某個具體的異常,需要同時檢查一場出現的位置是否在異常處理的有效作用范圍內,以及出現的異常是否是異常處理器聲明可以處理的異常類型或其子類型。當拋出異常時,Java虛擬機搜索當前方法包含的各個異常處理器,如果能找到可以處理該異常的異常處理器,則將代碼控制權轉向異常處理器中描述的處理異常的分支之中。
  首先簡單介紹一下main方法中各條字節碼指令所代表的意思:
  0 : 將int類型的常量i壓入操作數棧中,iconst_0后面跟的那個0代表常量的值為0;
  1:將一個int類型數據由保存到本地變量表,istort_1后面的1代表的是指向當前棧幀中局部變量表的索引值;
  2:將一個值為3的int類型的常量壓入操作數棧中。在這里指的是被除數3;
  3:從局部變量表加載一個int類型值到操作數棧中,這里指的是除數i;
  4:對兩個int類型的數據做除法;
  5:將兩數相除之后所得到的int類型數據保存到本地變量表;
  6:假如沒有發生異常的話,那么執行完goto到第14條語句,函數正常返回;
  9:假如發生了除零異常,就執行這條指令,將異常對象保存到局部變量表中;
  10:從局部變量表中加載剛才的那個異常對象到操作數中;
  11:調用異常對象的printStackTrace方法
  14:不管是正常完成還是異常完成,最終都會返回。
  在字節碼下方可以看到一個Exception table。那么它是什么東西呢?其實我們很容易能夠理解它就是異常表,也就是前面我們提過的異常處理器。我們可以明顯地觀察出,其實try-catch代碼塊編譯之后似乎沒有生成任何指令。那么Java語言中的try-catch放到字節碼當中對應什么東西呢?其實就是對應這個異常處理器。下面我們來解讀一下異常處理器:
  在try語句塊的執行過程中如果沒有拋出異常,那么這個異常處理器不會起作用。異常處理器的作用范圍是從字節碼的第2行到第6行,也就是from-to標明的范圍。假如編譯好的代碼里面第2~6句之間有一個類型為java.lang.ArithmeticException的異常實例被拋出,那么操作將轉移至第9句繼續執行,即進入catch語句塊的實踐步驟。假如說拋出的異常不是ArithmeticException實例,那么異常處理器就不能處理該異常,這個異常將返回給上一級的調用者。
  那假如try語句塊包含多個catch語句塊,在編譯好的代碼中會出現什么樣的結果呢?
  如果給定的try語句塊包含多個catch語句塊,那么在編譯好的代碼中,多個catch語句塊的內容將會連續排列,在異常表中也會有對應的連續排列的成員,它們的排列順序和源碼中catch語句塊的出現順序一致。main方法在執行時,如果try語句塊中拋出了一個異常,這個異常將會被多個catch語句塊捕獲。假如第一個catch不能捕獲異常(當然這里的第一個catch語句塊肯定是能處理ArithmeticException,我只是舉個例子),那么異常將交由第二個異常處理器來進行處理,這很容易理解。因為我在第二個catch語句塊中選擇的是將捕獲的異常拋出,所以在字節碼的第26行可以看到有一個athrow指令,在前面的學習當中我們知道它是拋出異常的意思,其實也就是對應著Java代碼中的throw new Exception()。在這里,我還要順便介紹一下Java創建一個對象的代碼在編譯之后會產生怎樣的字節碼。
  其實,剛才我所說的throw new Exception()對應athrow字節碼指令只說對了一半,它在編譯之后不僅僅只產生athrow這一條字節碼指令。因為它還對應著一個操作,也就是new一個Exception對象。Java語言實例化一個Exception對象將會產生三條字節碼指令,即上圖中19,22,23三行:
  為什么會有三條指令呢?dup是做什么的?我們下面一起來學習一下
  由于討論的是創建對象,所以在代碼throw new Exception()中我們不看throw,只看new Exception()這一部分代碼。
  new Exception()表達式的作用是:
  創建并默認初始化一個Exception對象;
  調用Exceptioon類的signature為()V的構造器;
  表達式的值為一個指向這個對象的引用
  對應字節碼,我們可以看到:
  new Exception()對應上面的1
  invokespecial Exception.()V對應上面的2
  那么3是怎么來的?
  回歸到字節碼,我們可以看到new字節碼指令的作用是創建指定類型的對象實例、對其進行默認初始化,并將指向該實例的一個引用壓入操作數棧頂;
  然后因為invokespecial會消耗操作數棧頂的引用作為傳給構造器的"this"參數,所以如果我們希望在invokespecial調用后在操作數棧頂還維持有一個指向新建對象的引用,就得在invokespecial之前先“復制”一份引用----這就是dup的來源。
  以上,就是對創建一個對象編譯之后產生的字節碼的解釋
  編譯finally語句塊
  剛才我們介紹了異常處理在字節碼層面的細節,但是我們還需要注意的是----由于finally能夠保證不管發生任何情況,都能夠執行語句塊中的代碼,所以在日常編碼過程中我們在可能發生異常的地方(或者是不會發生異常的地方)經常使用finally來釋放某些資源。
  下面我們從虛擬機層面來看看如何保證finally語句塊中的代碼一定會執行
  可以看到,其實編譯器是通過在每個分支后面增加冗余代碼的形式來保證finally語句塊中的代碼一定會被執行。這里和書上講的有點出入,書上在講解這一塊的時候還是用jsr、jsr_w、ret等程序控制轉移指令來解釋的,但是javac在很早之前就不再為finally語句生成jsr和ret指令了。
  如果程序在try語句塊中執行了return,那么代碼的行為如下:
  如果有返回值,將返回值保存在局部變量表;
  執行跟在后面的冗余finally語句塊中的代碼;
  在finally執行完之后,將事先保存在局部變量表中的返回值壓入操作數棧中之后返回。
  如果在try語句中拋出異常,那么代碼的行為如下:
  將異常保存在局部變量表中
  執行finally語句塊中的代碼
  在執行完finally語句塊中的代碼后,重新拋出這個事先保存好的異常。
  Java虛擬機中的同步(synchronization)使用monitor的進入和退出來實現的。無論顯式同步(有明確的monitorenter和monitorexit指令),還是隱式同步(依賴方法調用和返回指令實現)都是如此。
  在Java語言中,同步用得最多的地方可能是經synchronized所修飾的同步方法。同步方法并不是用monitorenter和monitorexit來實現的,而是由方法調用指令讀取運行時常量池中方法的ACC_SYNCHRONIZED標志來隱式實現的。
  monitorenter和monitorexit指令用于編譯同步語句塊
  編譯器必須確保無論方法以何種方式完成(正常結束或者是異常結束),方法中調用過的每條monitorenter指令都必須有對應的monitorexit指令得到執行。為了確保在方法異常完成時,monitorenter和monitorexit指令依然可以正確配對執行,編譯器會自動生成一個異常處理器,這個異常處理器宣稱自己可以處理所有異常,它的代碼用來執行monitorexit指令。
  到這里深入理解Java之java虛擬機干凈利落的規范總結就結束了,不足之處還望大家多多包涵!!覺得收獲的話可以點個關注收藏轉發一波喔,謝謝大佬們支持。
 

免責聲明:本文內容由互聯網用戶自發貢獻自行上傳,本網站不擁有所有權,也不承認相關法律責任。如果您發現本社區中有涉嫌抄襲的內容,請發送郵件至:operations@xinnet.com進行舉報,并提供相關證據,一經查實,本站將立刻刪除涉嫌侵權內容。

免費咨詢獲取折扣

Loading
主站蜘蛛池模板: 亚洲中文字幕无码中文字| 天堂网在线.www天堂在线资源| 国产精品人成视频国模| 久久性色av亚洲电影| 换脸国产av一区二区三区| 国产精品自产拍在线观看免费| 97亚洲欧美国产网曝97| 女人高潮内射99精品| 西西大胆午夜人体视频| 久久综合综合久久综合| 欧美伊人久久大香线蕉综合| 国产精品无码专区在线观看| 一日本道伊人久久综合影| 亚洲aⅴ一区二区三区在线| 青草青草久热精品视频在线观看| 久久精品人人做人人爽电影 | 欧美精品区一区二区三区| 黑色丝袜国产精品| 后入到高潮免费观看| 无码国产精品一区二区av| 四虎影视成人永久免费观看视频| 精品国产a∨无码一区二区三区 | 美女又黄又免费的视频| 97人妻人人揉人人躁人人| 亚洲精品乱拍国产一区二区三区| 人妻尝试又大又粗久久| 国产亚洲欧美人成在线| 毛片内射久久久一区| 色爽黄1000部免费软件下载| 久久久久黑人强伦姧人妻| 亚洲最大综合久久网成人| 日韩精品一区最新看| 国产一区二区四区在线观看 | 在线精品视频一区二区| 成人做爰视频www网站小优视频| 亚洲毛片无码不卡av在线播放| 欧美熟女视频一区二区免费| 国产精品久久人妻无码网站蜜臀| 国产精品国产av片国产| 欧美成人a在线网站| 制服亚洲欧美一区|