zoukankan      html  css  js  c++  java
  • 第17章 异常

    javac为remainder ()方法产生下列字节码序列:

    // The main bytecode sequence for remainder ();
    // Push local variable 0 {arg passed as
    0 iload_0 // dividend)
    // Push the minimum integer value
    1 ldc #1 <Integer -2147483648>

    // If the dividend isn't equal to the minimum
    // integer, jump to the remainder calculation
    3 if_icmpne 19

    // Push local variable 1 (arg pased as

    6 iload_l // divisor)

    // Push -1

    7 iconst_ml

    // If the divisor isn't equal to -1, jump
    // to the remainder calculation

    8 if_icmpne 19

    // This is an overflow case, bo throw an
    // exception. Create a new OverflowException,
    // push reference to it onto the stack

    11 new #4 <ClaBS OverflowException>
    14 dup //make a copy of the reference

    //Pop one copy of the reference and invoke
    // the <init> method of new OverflowException
    // object

    15 invokeapecial #10 <Method OverflowException()>

    // Pop the other reference to the
    // OverflowException and throw it

    18 athrow

    // Calculate the remainder
    // Puab local variable 0 (arg passed as
    19 iload_0 // dividend)
    // Push local variable 1 (arg passed as
    20 iload_l // divisor)
    // Pop divisor; pop dividend; calculate,push
    21 irem // remainder
    22 ireturn // Return int on top of stack (the remainder)

    // The bytecode sequence for the
    // catch (ArithmeticBxception) clause:

    // Pop the reference to the
    // ArithmoticException because it isn't used

    23 pop //by this catch clause.

    24 new #2 <Class DivideByZeroException>
    // Create and push reference to new object of
    // class DivideByZeroException.
    // 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

    27 dup // reference created by the dup,

    // Call the no-arg <init> method for the
    // DivideByZeroException to initialize it.

    // This instruction will pop the top reference
    // to the object.

    28 invokespecial #9 <Method DivideByZeroException()>

    // Fop the reference to a Throwable object, in
    // this case the DivideByZeroException,

    31 athrow // and throw the exception.
    方法remainder ()的字节码序列包含两个部分:第一部分是方法的正常执行路径,该部分指的是pc指针偏移量0到22;第二部分是catch子句,该部分指的是pc指针偏移量23到31。

    // Overflow can occur in division when dividing
    // the negative integer of the largest possible
    // magnitude (Integer.MIN_VALUE) by -1, because
    // this would Juat flip the sign, but there is no
    // way to represent that nunber in an int.
    if((dividend Integer.MIN_VALUE> &&(divisor==-1)){
    throw new OverflowException();
    }
    所有作为Error和RuntimeException的子类的异常都是未检验的。

    17.2异常表
    主字节码序列中的指令irem可能会抛出ArithmeticException异常。如果发生这种情况,Java 虚拟机将在表中査找异常,然后跳转到实现catch子句的字节码序列。每个捕获异常的方法都与异常表相关联,该异常表与方法的字节码序列一起送到Class文件中。每一个被try语句块捕获的异常都与异常表中的一个入口(项)相对应。异常表中的每个入口都包括四部分信息:

    •起点。

    •终点。

    •将要跳转到的字节码序列中的pc指针偏移量。

    •被捕获的异常类的常量池索引。

    下面是NitPickyMath类的remainder ()方法的异常表:

    Exception table:

    from to target type

    I9 23 23 <Class java.lang.ArithmeticException>

    上述异常表说明,ArithmeticException异常在pc指针偏移量19到22 (含)中被捕获。try语句块的终点值在“to”栏中列出。这个终点值总是比捕获异常位置的pc指针偏移量的最大值还要大1。在这个例子中,终点值为23,但捕获异常位置的pc偏移量最大值为22。偏移量19到22 (含)之间的语句对应于实现remainder ()内try语句块代码的字节码序列。上述表格中列出的target栏指出了如果ArithmeticException异常在pc指针偏移量19到22 (含)之间抛出,pc指针偏移量将要跳转到的位置。

    如果异常在方法执行时抛出,Java虚拟机将会在整个异常表中搜寻相匹配的项。如果当前程序计数器在异常表入口所指定的范围内,而且所抛出的异常类是该入口所指向的类(或为指定类的子类),那么该入口即为所搜寻的入口。Java虚拟机按照每个入口在表中出现的顺序进行检索。当遇到第一个匹配项时,虚拟机将程序计数器设为新的pc指针偏移量位置,然后从该位置 继续执行。如果没有发现相匹配的项,虚拟机将当前栈帧从栈中弹出,再次抛出同样的异常。 当Java虚拟机弹出当前栈帧时,虚拟机马上终止当前方法的执行,并且返回至调用本方法的方法 中,但是并非继续正常执行该方法,而是在该方法中拋出同样的异常,这就使得虚拟机在该方 法中再次执行同样的搜寻异常表的操作。

    Java程序员可以使用throw语句抛出异常,正如remainder ()方法中的catch ( Arithmetic Exception)子句,这里创建了异常DivideByZcjroExceplion,并将其抛出。执行抛出异常操作的 字节码如表17-1所示。

    指令athrow从栈顶端弹出宇,并假设它是一个对象的引用,该对象为Throwable类的子类的实例(或者就是Throwable类的实例)。所抛出异常的类型由弹出的对象引用类型决定。

  • 相关阅读:
    linux-01Red Hat Enterprise Linux 7(RHEL7)配置静态IP地址
    Linux下Tomcat重新启动
    获取root权限
    -save 和 --save-dev的区别
    周五的听歌时间
    十月第二周计划
    国庆计划
    周末计划
    前端基础进阶系列
    前端基础进阶(二):执行上下文详细图解
  • 原文地址:https://www.cnblogs.com/mongotea/p/11980084.html
Copyright © 2011-2022 走看看