亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

Java虛擬機處理異常的最佳方式

2024-07-14 08:43:53
字體:
來源:轉載
供稿:網友

前言

歡迎來到Under The Hood專欄。本專欄旨在讓Java開發人員一瞥在運行Java程序底層的神秘機制。本月的文章繼續討論Java虛擬機的字節碼指令集,方法是檢查Java虛擬機處理異常拋出和捕獲的方式,包括相關的字節碼。本文不討論finally條款 - 這是下個月的主題。后續文章將討論字節碼系列的其他成員。

下面話不多說了,來一起看看詳細的介紹吧

Exceptions

Exceptions允許您順利處理程序運行時發生的意外情況。要演示Java虛擬機處理異常的方式,請考慮一個名為NitPickyMath的類。它提供了對整數執行加法,減法,乘法,除法和余數的方法。NitPickyMath在溢出,下溢和被零除的條件下拋出已檢查的異常。Java虛擬機將在整數除零上拋出一個ArithmeticException,但不會在溢出和下溢上拋出任何異常。方法拋出的異常定義如下:

class OverflowException extends Exception {}class UnderflowException extends Exception {}class DivideByZeroException extends Exception {}

捕獲和拋出異常的簡單方法是remainder類的方法NitPickyMath:

static int remainder(int dividend, int divisor) throws DivideByZeroException { try {  return dividend % divisor; } catch (ArithmeticException e) {  throw new DivideByZeroException(); }}

該remainder方法僅在傳遞兩個int參數時執行余數運算。如果余數運算的除數為零,則余數運算拋出一個ArithmeticException。這個方法捕獲了這個ArithmeticException并拋出一個DivideByZeroException。

DivideByZeroException和ArithmeticException之間的差別是DivideByZeroException是一個檢查異常,并且ArithmeticException是未經檢查。因為ArithmeticException是非受檢異常,所以方法不需要在throws子句中聲明此異常,即使它可能會拋出它。任何屬于Error或者RuntimeException子類的異常都是非受檢異常。(ArithmeticException是RuntimeException的子類。)通過捕獲ArithmeticException然后拋出DivideByZeroException,該remainder方法強制其客戶端處理除零異常的可能性,通過捕獲它或在自己的throws子句中聲明DivideByZeroException。這是因為已檢查的異常,例如DivideByZeroException,拋出方法必須由方法捕獲或在方法的throws子句中聲明。未經檢查的異常(例如ArithmeticException,不需要在throws子句中捕獲或聲明)。

javac為該remainder方法生成以下字節碼序列:

The main bytecode sequence for remainder:
   0 iload_0               // Push local variable 0 (arg passed as divisor)
   1 iload_1               // Push local variable 1 (arg passed as dividend)
   2 irem                  // Pop divisor, pop dividend, push remainder
   3 ireturn               // Return int on top of stack (the remainder)
The bytecode sequence for the catch (ArithmeticException) clause:
   4 pop                   // Pop the reference to the ArithmeticException
                           // because it isn't used by this catch clause. 
   5 new #5 <Class DivideByZeroException>
                       // Create and push reference to new object of class
                      // DivideByZeroException.
DivideByZeroException
   8 dup           // Duplicate the reference to the new
                           // object on the top of the stack because it 
                           // must be both initialized 
                        // and thrown. The initialization will consume
                       // the copy of the reference created by the dup.
   9 invokenonvirtual #9 <Method DivideByZeroException.<init>()V>
                      // Call the constructor for the DivideByZeroException
                      // to initialize it. This instruction
                     // will pop the top reference to the object.
  12 athrow          // Pop the reference to a Throwable object, in this
                           // case the DivideByZeroException, 
                           // and throw the exception.

該remainder方法的字節碼序列有兩個獨立的部分。第一部分是該方法的正常執行路徑。這部分從pc偏移0到3。第二部分是catch子句,它從pc偏移4到12。

主字節碼序列中的irem指令可能會拋出一個ArithmeticException。如果發生這種情況,Java虛擬機知道通過查找表中的異常來跳轉到實現catch子句的字節碼序列。捕獲異常的每個方法都與一個異常表相關聯,該異常表在類文件中與方法的字節碼序列一起傳遞。每個try塊捕獲的每個異常在異常表中都有一個條目。每個條目都有四條信息:起點和終點,要跳轉到的字節碼序列中的pc偏移量,以及正被捕獲的異常類的常量池索引。remainder類的NitPickyMath方法的異常表如下所示:

Exception table:
   from   to  target type
     0     4     4   <Class java.lang.ArithmeticException>

上面的異常表指示從pc偏移0到3(包括0),表示ArithmeticException將被捕獲的范圍。在標簽“to”下面的表中列出的是try塊的端點值,它總是比捕獲異常的最后一個pc偏移量多一。在這種情況下,端點值列為4,捕獲到異常的最后一個pc偏移量為3。此范圍(包括0到3)對應于在remainder的try塊內實現代碼的字節碼序列。如果ArithmeticException在pc偏移量為0和3之間(包括0和3)之間拋出,則表中列出的"to"就是跳轉到的pc偏移量。

如果在執行方法期間拋出異常,Java虛擬機將在異常表中搜索匹配的條目。如果當前程序計數器在條目指定的范圍內,并且拋出的異常類是由條目指定的異常類(或者是指定異常類的子類),則異常表條目匹配。Java虛擬機按照條目在表中的顯示順序搜索異常表。找到第一個匹配項后,Java虛擬機會將程序計數器設置為新的pc偏移位置并繼續執行。如果未找到匹配項,Java虛擬機將彈出當前堆棧幀并重新拋出相同的異常。當Java虛擬機彈出當前堆棧幀時,它有效地中止當前方法的執行并返回調用此方法的方法。但是,不是在前一個方法中繼續正常執行,而是在該方法中拋出相同的異常,這會導致Java虛擬機經歷搜索該方法的異常表的相同過程。

Java程序員可以使用throw語句拋出異常,例如remainder中的一個子句catch(ArithmeticException),其中一個 DivideByZeroException創建并拋出。執行拋出的字節碼如下表所示:

 

OPCODE OPERAND(S) DESCRIPTION
athrow (none) pops Throwable object reference, throws the exception

 

athrow指令從堆棧中彈出頂部字節,并且會認為它是一個Throwable子類的引用(或Throwable本身)。拋出的異常是彈出對象引用定義的類型。

Play Ball!: a Java virtual machine simulation

下面的applet演示了一個執行一系列字節碼的Java虛擬機。模擬中的字節碼序列由javac生成。

類的playBall方法如下所示:

class Ball extends Exception {}class Pitcher { private static Ball ball = new Ball(); static void playBall() {  int i = 0;  while (true) {   try {    if (i % 4 == 3) {     throw ball;    }    ++i;   }   catch (Ball b) {    i = 0;   }  } }}

javac為該playBall方法生成的字節碼如下所示:

0 iconst_0             // Push constant 0
   1 istore_0         // Pop into local var 0: int i = 0;
           // The try block starts here (see exception table, below).
   2 iload_0              // Push local var 0
   3 iconst_4             // Push constant 4
   4 irem                 // Calc remainder of top two operands
   5 iconst_3             // Push constant 3
   6 if_icmpne 13    // Jump if remainder not equal to 3: if (i % 4 == 3) {
                    // Push the static field at constant pool location #5,
                   // which is the Ball exception itching to be thrown
   9 getstatic #5 <Field Pitcher.ball LBall;>
  12 athrow        // Heave it home: throw ball;
  13 iinc 0 1       // Increment the int at local var 0 by 1: ++i;
                    // The try block ends here (see exception table, below).
  16 goto 2               // jump always back to 2: while (true) {}
                          // The following bytecodes implement the catch clause:
  19 pop              // Pop the exception reference because it is unused
  20 iconst_0             // Push constant 0
  21 istore_0             // Pop into local var 0: i = 0;
  22 goto 2            // Jump always back to 2: while (true) {}
Exception table:
   from   to  target type
     2    16    19   <Class Ball>
     ```

該playball方法永遠循環。每四次循環,playball拋出Ball并抓住它,只是因為它很有趣。因為try塊和catch子句都在無限循環中,所以樂趣永遠不會停止。局部變量i從0開始,每次遞增遞增循環。當if語句出現true時,每次i等于3 時都會發生Ball異常,拋出異常。

Java虛擬機檢查異常表并發現確實存在適用的條目。條目的有效范圍是2到15(包括兩者),異常在pc偏移12處拋出。條目捕獲的異常是類Ball,拋出的異常是類Ball。鑒于這種完美匹配,Java虛擬機將拋出的異常對象推送到堆棧,并繼續在pc偏移19處執行catch子句,這里僅將int i重置為0,并且循環重新開始。

要驅動模擬,只需按“步驟”按鈕。每次按下“Step”按鈕都會使Java虛擬機執行一個字節碼指令。要開始模擬,請按“重置”按鈕。要使Java虛擬機重復執行字節碼而不需要進一步操作,請按“運行”按鈕。然后,Java虛擬機將執行字節碼,直到按下“停止”按鈕。applet底部的文本區域描述了要執行的下一條指令??鞓伏c擊。

英文原文:https://www.javaworld.com/article/2076868/how-the-java-virtual-machine-handles-exceptions.html

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品成人一区二区三区吃奶| 自拍偷拍亚洲一区| 欧美性猛交xxxx富婆弯腰| 国产黑人绿帽在线第一区| 影音先锋欧美在线资源| 久久久av免费| 热久久免费视频精品| 韩国精品美女www爽爽爽视频| 精品自拍视频在线观看| 中文字幕日韩免费视频| 亚洲图片在线综合| 一个人看的www久久| 欧美另类交人妖| 国产精品999| 欧美极品美女视频网站在线观看免费| 欧美午夜精品久久久久久浪潮| 亚洲а∨天堂久久精品喷水| 久久久人成影片一区二区三区观看| 日韩av手机在线观看| 国产精品一区二区电影| 国产丝袜一区视频在线观看| 亚洲精品久久久久| 国产精品69久久| 亚洲精品www久久久久久广东| 日韩欧美在线免费观看| 琪琪第一精品导航| www日韩中文字幕在线看| 日韩精品久久久久久久玫瑰园| 91精品久久久久| 亚洲精品aⅴ中文字幕乱码| 欧美三级免费观看| 国产亚洲精品美女| 亚洲片在线资源| 亚洲综合日韩中文字幕v在线| 中文亚洲视频在线| 久久久久久成人精品| 色在人av网站天堂精品| 中文字幕亚洲国产| 久久久久久这里只有精品| 亚洲午夜国产成人av电影男同| 亚洲国产精品大全| 北条麻妃一区二区三区中文字幕| 亚洲美女又黄又爽在线观看| 91精品国产91久久久久久| 亚洲精品日韩激情在线电影| 这里只有精品视频| 欧美激情免费在线| 国产精品十八以下禁看| 91午夜理伦私人影院| 精品色蜜蜜精品视频在线观看| 亚洲欧美中文字幕在线一区| xvideos成人免费中文版| 精品久久久久久久久久| 国产z一区二区三区| 亚洲高清一区二| 欧美精品在线看| 大胆欧美人体视频| 中文字幕亚洲综合久久| 91国产精品91| 亚洲毛片在线观看.| 欧美日韩综合视频| 久久精品国产一区二区电影| 九九热99久久久国产盗摄| 国产视频亚洲精品| 欧美专区日韩视频| 亚洲美女精品成人在线视频| 亚洲男人天堂久| 欧美性猛交xxxx富婆弯腰| 91亚洲人电影| 久久九九有精品国产23| 欧美一区二区影院| 欧美日韩中文在线| 国产精品在线看| 热久久美女精品天天吊色| 亚洲丝袜av一区| 亚洲国产精品免费| 中文字幕一精品亚洲无线一区| 在线丨暗呦小u女国产精品| 欧美极品欧美精品欧美视频| 欧美激情亚洲国产| 国产精品一久久香蕉国产线看观看| 欧美午夜宅男影院在线观看| 91精品久久久久久久久久| 欧美亚洲另类激情另类| 久久99国产精品自在自在app| 亚洲女人天堂成人av在线| 亚洲精品电影在线观看| 最近的2019中文字幕免费一页| 亚洲www视频| 国产欧美 在线欧美| 欧美区在线播放| 欧美xxxx做受欧美| 福利一区福利二区微拍刺激| 成人www视频在线观看| 欧美电影免费看| 亚洲深夜福利在线| 亚洲人精品午夜在线观看| 精品久久久久久亚洲精品| 国产亚洲精品一区二区| 久久人91精品久久久久久不卡| 亚洲成人教育av| 久久久久北条麻妃免费看| 亚洲已满18点击进入在线看片| 久久精品99国产精品酒店日本| 亚洲人午夜精品免费| 在线电影欧美日韩一区二区私密| 91极品女神在线| 北条麻妃一区二区三区中文字幕| 久热精品视频在线观看一区| 97福利一区二区| 欧美成人免费一级人片100| 日韩av大片免费看| 欧美视频在线观看免费| 91久久久亚洲精品| 97在线视频免费播放| 国产日产欧美a一级在线| 久久久久久尹人网香蕉| 亚洲黄色www| 亚洲精品一区在线观看香蕉| 国产+成+人+亚洲欧洲| 2018日韩中文字幕| 国产精品亚洲一区二区三区| 成人免费在线视频网址| 亚洲а∨天堂久久精品喷水| 热99精品只有里视频精品| 亚洲国产精品人人爽夜夜爽| 国产这里只有精品| 欧美日韩一区二区在线播放| 成人福利网站在线观看| 亚洲三级av在线| 亚洲视频网站在线观看| 久久精品视频va| 最新国产精品拍自在线播放| 亚洲精品wwww| 性欧美暴力猛交69hd| 欧美日韩一区二区三区在线免费观看| 美女av一区二区| 亚洲成人精品久久| 亚洲丁香婷深爱综合| 中文字幕精品www乱入免费视频| 欧美重口另类videos人妖| 久久久亚洲成人| 色与欲影视天天看综合网| www.日本久久久久com.| 亚洲欧美激情另类校园| 自拍偷拍免费精品| 欧美激情2020午夜免费观看| 国产精品精品久久久久久| 91亚洲精品久久久久久久久久久久| 国产欧美精品在线播放| 久久久久国色av免费观看性色| 国产美女久久久| 国产在线a不卡| 国产精品免费视频xxxx| 欧美激情综合色综合啪啪五月| 久久久这里只有精品视频| 性亚洲最疯狂xxxx高清| 2019国产精品自在线拍国产不卡| 97精品国产97久久久久久免费| 国产精品中文在线| 精品精品国产国产自在线| 国产精品嫩草影院久久久| 国产精品成久久久久三级| 亚洲国产婷婷香蕉久久久久久|