JAVA异常处理


Try就像一个警报器,任何进入他领域的陌生人,这个警报器就会发出警报声,然后把陌生人交给catch处理。

try语句中发生了任何异常,try语句块就会把控制权转移给catch语句,如果这个异常与catch语句相匹配,那么控制流程就进入这个catch中,否则,匹配下一个catch语句。

在一个方法中可以有多个try语句,虽然很少这样做,同时,一个try语句也可以有多个catch语句。

   

  请看如下代码:

 

package MyPackage;

public class ExceptionTest {

	public static void main(String[] args) {
		int i=0;
		int j =1;
		try{
			System.out.println(j/i);
		}catch(ArithmeticException ex){
			
		}catch(Exception ex){
			
		}
		
	}

}


在这段代码中i/j会抛出一个ArithmeticException异常,然后,控制权转移到第一个catch语句,catch语句可能会进行一些异常处理。

现将这个代码反汇编成字节码,如下:

先来解释一下这个main方法的字节码:偏移量0到3的字节码(iconst_0  to  istore_2)对于源代码中的如下两行语句,主要完成初始化操作。

                int i=0;

                int j =1;

偏移量4到13的字节码(getstatic 到第一个goto)对于源代码的try语句块,如下:

         try{

                System.out.println(j/i);

         }

接下来的偏移量为16到17的字节码 ( astore_3到goto)对应于源代码中的第一个catch语句。

最后两行偏移量为20到21的字节码(astore_3 到 return)对应于源代码中的第二个catch语句。

接下来看到的是一个Exception table(异常表)。这个表由两行组成,分别对应于try语句的两个catch;java虚拟机为会每一个catch,在Exception table中创建一个条目。

 

 

在这段字节码中,idiv指令完成了核心功能,除法操作。这个指令在除数为零时会抛出一个ArithmeticException异常。如果idiv指令抛出了一个ArithmeticException异常,那么java虚拟机就会去Exception table中查找这个catch语句(通过比较第四列type中的字符串),找到了这个catch之后,还要看一看from和to列,如果idiv指令所在的偏移量在这个form 和to值之间,就匹配成功,然后java虚拟机会跳到traget值对于的字节码;

如果java虚拟机在Exception table中没有找到匹配的异常,java虚拟机就会弹出当前栈帧,并将这个异常压入调用这个方法的栈帧中,然后重新抛出异常,执行刚才所说的操作。

 

现在解释一下Exception table,如果一个方法有try…catch语句,那么这个方法就有会一个Exception table,java虚拟机会为每一个catch,在Exception table中创建条目。每一个条目由四列组成,每一列的含义如下:

from:try语句所保护的字节码的起始偏移量。

to:try语句所保护的字节码的终点。

Target:要跳转到的catch语句(偏移量)

Type:catch类型

from …to标示了try语句块的保护范围,如果在这个范围内抛出了一个type类型的异常,就会跳转到target所标示的catch语句块中。

   

  现在,再描述一下整个过程,当java虚拟机执行到偏移量为9的idiv指令时,抛出了一个ArithmeticException异常。然后java虚拟开始查找这个方法的Exception table,通过比较type列,java虚拟机找到了一个条目,接下来java虚拟机会用刚才抛出异常的idiv指令的偏移量,来看看这个偏移量是否在form…to之间,如果在,就匹配,跳转到target所标示的catch中。

 

   在java中可以throw显示抛出一个异常,同字节码中也有对于的指令,这个指令是athrow指令。 

 

一个方法主要通过两种方式返回,一种是正常返回,一种是异常返回。

正常返回就是那些通过return方式返回的,当然了,如果返回类型是void,可能不必在源代码中显示使用return。

异常返回就是方法中的某个指令抛出了一个异常,从而迫使这个方法返回。 如果一个方法抛出了一个异常,java虚拟机会在Exception table中查找相应的异常,如果找到了,则按照Exception table中所指示的方式进行处理。否则,java虚拟机会弹出当前方法的栈帧,然后将这个异常对象的引用重新压入调用这个方法的栈帧,这样就使得这个异常在掉用者中重新抛出。             

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值