Java异常处理使用Throwable而不是Exception

本文探讨了一个线上系统遇到的奇怪问题,即某请求处理失败,但日志未记录错误信息,catch未执行而finally却执行了。通过分析,发现是由于抛出了非Exception子类的异常。文章深入解析了Exception与Error的区别,强调了在编码时使用catch(Throwable e)的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线上问题

近期在线上系统中遇到了一个奇怪的问题,某个请求处理失败了,但是日志里没有任何错误信息,catch(Exception e) {}代码块根本没有执行,因此直接跳过了错误处理逻辑,但是finally{}块却执行了。根据此现象我们推测出很可能是代码块抛出了非Exception子类的异常。果然,将catch Exception改为catch Throwable后, 日志中出现了java.lang.IncompatibleClassChangeError异常。因为此异常是Error而不是Exception的子类,所以导致了出现catch{}没有执行但finally执行了的现象。

关于Exception

异常.png
在很多入门书上都会有类似于"Exception是可恢复的而Error往往是不可恢复的系统严重错误"这样的内容,当然,这句话本身是没问题的,问题在于即便是Error错误我们也应该捕获一下,至少要记一下日志,如果忽略掉的话就会出现上面这种莫名其妙失败但又找不到线索的情况。
经查,报java.lang.IncompatibleClassChangeError的原因是最近一次上线时引入了新的业务jar包,此依赖的某个传递依赖版本跟原有系统中的jar版本有冲突,导致JVM在执行时报错。这个问题之所以在测试时没有发现,还有一个原因,就是只有在执行到特定逻辑时才会触发,并不是每次都会出现,非常隐蔽。

如果偶尔看过Netty的代码,你会发现Netty所有的catch, 最后都是以catch(Throwable e)结尾的,而不是Exception。我们在编码时也应该以catch Throwable兜底, 不要再使用Exception了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值