前言Java中一个众所周知的知识点就是异常捕获,try...catch...finally组合,但是很多人不知道有是Java的缺陷,还是异常实现的一点不足。下面我就通过一个非常简单的实验来给大家演示一下效果。我希望你会觉得它很有趣。模拟1.自定义异常这里我们先写一个自定义的业务异常,专门用来抛出。2.模拟异常然后,我们写一个测试方法来捕获并抛出一个空指针异常。看看效果,OK没问题。接下来我们加finally看看。看看效果,OK没问题。接下来我们通过在finally中抛出异常来做到这一点。看效果,发现catch异常被覆盖了。这种场景虽然很特殊,但在Java对异常的实现中其实是美中不足,因为异常永远不应该被当作程序错误的标志而被忽略,但异常确实在这种场景中丢失了。接下来我们测试另一种情况,在finally中使用return,看看会发生什么。看效果,发现catch中捕捉到的异常干脆就消失了,就好像从来没有来过一样。最后,让我们来演示另一个您可能在工作中做过或看到的莫名其妙的事情。我们修改一下这个测试方法,看看代码。简单描述一下,如果你调用了其他类的一个查询方法,那个方法可能会习惯性的try..catch..finally,finally执行一些最后必须执行的操作。可能有几十个业务逻辑处理好吧,你很可能会习惯性的做一些判断,抛出异常。不信,当一个项目进入中期甚至赶进度的时候,很多人已经把代码写得生搬硬套,手足无措,或者在别人的基础上改代码,你很可能就赢了不要太在意它。逐行看那些代码里有什么,正好测试的时候没有大问题。那么结果可能如下。你会发现,你一开始故意抛出的那个捕获查询方法异常的东西一点作用都没有,你也不知道跑到哪里去了。你怎么看都找不到。下面莫名其妙的异常,以后想不起来就算了。究其原因,其实是Java异常实现上的不足。异常是程序错误的标志,不容忽视,更不用说finally的常用行为,直接或间接导致异常丢失。《Thinking In Java》的作者已经明确的指出了这个异常,并且认为这是一个比较严重的缺陷,一个可能导致异常完全消失的缺陷,而且是以一种更加隐蔽和不易察觉的方式。另一方面,C++处理得很好,将在处理第一个异常之前抛出第二个异常的情况视为严重的编程错误。总结知道了这个缺陷之后,其实就很容易避免了。1.避免在finally中抛出异常;2.避免在finally中使用return;3、在catch中,一定要养成在log.error中记录异常日志的好习惯,因为日志肯定会被记录下来,至少不会让你毫无头绪。最后,我将演示添加日志的效果。只要是抓到的,我都会添加日志,这样我就不会错过。原文章纯手打,一篇一篇,键盘满血。如果觉得有帮助,请给我推荐~我致力于分享我的工作经验和有趣的故事。喜欢的话可以去首页关注哦~
