资讯专栏INFORMATION COLUMN

Java异常处理12条军规

zeyu / 524人阅读

摘要:非检查异常是不需要在子句中声明的异常。在高执行级别,应记录此类异常。是最为严重的运行时错误,几乎是不可能恢复和处理,一些示例是,和。捕获异常时,也不要捕获范围太大,例如捕获,相反,只捕获你能处理的异常,应该处理的异常。

摘要: 简单实用的建议。

原文:Java异常处理12条军规

公众号:Spring源码解析

Fundebug经授权转载,版权归原作者所有。

在Java语言中,异常从使用方式上可以分为两大类:

CheckedException

UncheckedException

在Java中类的异常结构图如下:

可检查异常需要在方法上声明,一般要求调用者必须感知异常可能发生,并且对可能发生的异常进行处理。可以理解成系统正常状态下很可能发生的情况,通常发生在通过网络调用外部系统或者使用文件系统时,在这种情况下,错误是可能恢复的,调用者可以根据异常做出必要的处理,例如重试或者资源清理等。

非检查异常是不需要在throws子句中声明的异常。JVM根本不会强制您处理它们,因为它们主要是由于程序错误而在运行时生成的。它们扩展了RuntimeException。最常见的例子是NullPointerException 可能不应该重试未经检查的异常,并且正确的操作通常应该是什么都不做,并让它从您的方法和执行堆栈中出来。在高执行级别,应记录此类异常。

Error是最为严重的运行时错误,几乎是不可能恢复和处理,一些示例是OutOfMemoryError,LinkageError和StackOverflowError。它们通常会使程序或程序的一部分崩溃。只有良好的日志记录练习才能帮助您确定错误的确切原因.

在异常处理时的几点建议:

1. 永远不要catch中吞掉异常,否则在系统发生错误时,你永远不知道到底发生了什么
catch (SomeException e) {  
    return  null;
}
2. 尽量使用特定的异常而不是一律使用Exception这样太泛泛的异常
public void foo() throws Exception { //错误的做法}
public void foo() throws MyBusinessException1, MyBusinessException2 { //正确的做法}

一味的使用Exception,这样就违背了可检查异常的设计初衷,因为调用都不知道Exception到底是什么,也不知道该如何处理。捕获异常时,也不要捕获范围太大,例如捕获Exception,相反,只捕获你能处理的异常,应该处理的异常。即然方法的声明者在方法上声明了不同类型的可检查异常,他是希望调用者区别对待不同异常的。

3. Never catch Throwable class

​永远不要捕获Throwable,因为Error也是继承自它,Error是Jvm都处理不了的错误,你能处理?所以基于有些Jvm在Error时就不会让你catch住。

4. 正确的封装和传递异常**

不要丢失异常栈,因为异常栈对于定位原始错误很关键

catch (SomeException e) {throw  new MyServiceException("Some information: " + e.getMessage());  //错误的做法}

一定要保留原始的异常:

catch (SomeException e) {   throw new MyServiceException("Some information: " , e);  //正确的打开方式}
5. 要打印异常,就不要抛出,不要两者都做
catch (SomeException e) {   
    LOGGER.error("Some information", e);
    throw e;
}

这样的log没有任何意义,只会打印出一连串的error log,对于定位问题无济于事。

6. 不要在finally块中抛出异常

如果在finally中抛出异常,将会覆盖原始的异常,如果finally中真的可能会发生异常,那一定要处理并记录它,不要向上抛。

7. 不要使用printStackTrace

要给异常添加上有用的上下文信息,单纯的异常栈,没有太大意义

8. Throw early catch late

异常界著名的原则,错误发生时及早抛出,然后在获得所以全部信息时再捕获处理.也可以理解为在低层次抛出的异常,在足够高的抽象层面才能更好的理解异常,然后捕获处理。

9. 对于使用一些重量级资源的操作,发生异常时,一定记得清理

如网络连接,数据库操作等,可以用try finally来做clean up的工作。

10. 不要使用异常来控制程序逻辑流程

我们总是不经意间这么做了,这样使得代码变更丑陋,使得正常业务逻辑和错误处理混淆不清;而且也可能会带来性能问题,因为异常是个比较重的操作。

11. 及早校验用户的输入

在最边缘的入口校验用户的输入,这样使得我们不用再更底层逻辑中处处校验参数的合法性,能大大简化业务逻辑中不必要的异常处理逻辑;相反,在业务中不如果担心参数的合法性,则应该使用卫语句抛出运行时异常,一步步把对参数错误的处理推到系统的边缘,保持系统内部的清洁。

12. 在打印错误的log中尽量在一行中包含尽可能多的上下文
LOGGER.debug("enter A");LOGGER.debug("enter B"); //错误的方式
LOGGER.debug("enter A, enter B");//正确的方式

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/77572.html

相关文章

  • 20W字囊括上百个前端面试题的项目开源了

    摘要:字囊括上百个前端面试题的项目开源了这个项目是什么项目内容这个项目目前在上刚刚开源主要内容如下前端面试题主要整理了高频且有一定难度的前端面试题对这些面试题进行解读前端原理详解针对一些有一定难度面试题涉及的知识点进行详解比如涉及的编译原理响应式 20W字囊括上百个前端面试题的项目开源了 这个项目是什么? 项目内容 这个项目目前在GitHub上刚刚开源,主要内容如下: 前端面试题: 主要整...

    Euphoria 评论0 收藏0
  • 从“雅虎军规”看性能优化

    摘要:避免重定向重定向用和状态码,下面是一个有状态码的头浏览器会自动跳转到域指明的。除此之外还有别的跳转方式元标签和,但如果你必须得做重定向,最好用标准的状态码,主要是为了让返回按钮能正常使用。要提高性能,优化这些响应至关重要。 showImg(https://segmentfault.com/img/bVbmMsz?w=652&h=367);一直以来,性能优化是开发的重中之中,而提及 前端...

    BlackMass 评论0 收藏0
  • 从“雅虎军规”看性能优化

    摘要:避免重定向重定向用和状态码,下面是一个有状态码的头浏览器会自动跳转到域指明的。除此之外还有别的跳转方式元标签和,但如果你必须得做重定向,最好用标准的状态码,主要是为了让返回按钮能正常使用。要提高性能,优化这些响应至关重要。 showImg(https://segmentfault.com/img/bVbmMsz?w=652&h=367);一直以来,性能优化是开发的重中之中,而提及 前端...

    Kyxy 评论0 收藏0

发表评论

0条评论

zeyu

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<