Java 异常丢失 现象

在Java中,执行如下代码:

public class AException extends Exception{
	public String toString(){
		return "A";
	}
}

public class BException extends Exception{
	public String toString(){
		return "B";
	}
}
public class Test {
	public static void fun(){
		try{
			try{
				throw new AException();
			}finally{
				throw new BException();
			}
		}catch(Exception e){
			System.out.println(e);
		}

	}
	public static void main(String[] args) {
		fun();
	}
}

会发现输出结果为:

B

即在Test的fun()方法中原本被抛出的AException并没有被捕获。这是由于Java虚拟机的机制造成的一点缺陷。

解释:由于在finally中的代码一般是关闭资源的代码(关闭文件、网络链接等),所以当程序执行至try/catch代码块的“边界处”时,便会转入finally代码块,而throw语句在字节码层面并非原语操作,所以当上面程序在执行到

throw new AException();

时,jvm会将要抛出的异常的对象的引用存放到一个局部变量里,并将该变量存到方法栈的栈顶等待弹出,此时程序计数器指针指向finally内的代码,遇到下一个要抛出的异常,该异常则顶替AException的对象引用所在位置,所以程序只会输出:B

上述异常丢失现象在Java1.8版本中依然存在。

同理,在finally里也不要处理返回值。(当返回值在finally块外返回时,由于throw并非原子语句,所以会用中间变量存储中间值,导致finally内处理的返回值并不能体现在返回的实际值上)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值