Java异常处理的最佳实践

Wesley13
• 阅读 254

Java异常处理的最佳实践

为什么要有最佳实践

我们在写程序是不可避免的要对代码进行异常处理,但是有时对异常的处理会使我们的程序变的更加糟糕,这是我们所不想看到的。所以,我们再进行异常处理时需要遵循一定的套路,来降低异常处理对我们程序的影响。

异常产生的原因

一般来说,java中的异常会产生于一下三种情况:

  1. 编程错误导致的异常,例如NullPointerException 和 IllegalArgumentException。这类的异常一旦发现,必须通过修改代码来解决。
  2. 资源错误导致的异常,例如网络资源socket、文件资源等。这类的异常出现时往往会以记录日志,挂起程序或者进行重试来作为解决方法。
  3. 输入数据导致的异常,例如输入的JSON数据与程序中所指定的规范不一致,由此产生数据无法正常解析所抛的异常。这类的异常发生时,需要逐步调试程序或输入的数据。

Java异常的分类

java中定义了两种异常:

  • Checked Exception:该类异常直接继承自Exception类。在调用抛出checked exception的API时,必须使用catch进行异常处理或者将该异常throw出去,否则代码不能通过编译。
  • Unchecked Exception:该类异常继承自Runtime Exception,Runtime Exception也继承自Exception类,该类异常不需要显式的进行处理就可以进行编译。

进行异常处理的最佳实践

异常选择

对于程序可以进行处理的异常,一般选择通过Checked Exception进行抛出,程序在catch住一个异常之后,可以选择记录日志或者恢复数据或者进行别的操作。
对于程序无法处理的异常,一般抛出Unchecked Exception,将异常抛往更高层的逻辑进行处理,当然Unchecked Exception也是可以进行catch的,当所有的代码均没有对该异常进行处理时,该异常会被交给应用容器进行处理。

在异常处理中释放资源

在各种IO中,一般都会有异常处理,再进行Checked Exception处理时一般在finally中关闭资源。

SQLException一般会被转换成Unchecked Exception

数据库异常一般来说都是连接断掉或者是没有权限等问题,这些在代码里面没法进行处理,因此应该抛出Unchecked Exception。对于某些数据库异常,我们虽然无法解决根本问题,但是仍然是需要进行处理的,比如插入数据是失败,我们应该在代码中捕获该异常,并将原始数据记录下来。

不要使用异常作流程控制

生成栈回溯是非常昂贵的,栈回溯的价值是在于调试。在流程控制中,栈回溯是应该避免的,因为客户端仅仅想知道如何继续。

使用异常进行业务数据校验

对于需要用户输入有要对其进行业务性校验的需求,可以在业务校验失败时抛出自定义异常来告知失败的原因。
例如:在登陆功能中,如果身份校验失败,可以抛出相应的异常到控制器,然后有控制器进行数据输出。

不要忽略异常

针对大多数异常来说,不要使用空的catch块来处理异常。

尽量不要捕捉高级别的异常

高级别的异常会将低级的异常信息吃掉,因此再进行处理时应该尽量捕捉具体的异常类型。
比如,使用Exception作为catch的对象就是一个极端的例子,任何情况下都不要catch Exception这个类,因为这样做毫无意义。

只处理一次

我看到过有人在写代码时catch到了一个异常,然后logger.error(e)进行处理,然后又把这个异常throw出去了,这会导致该异常被处理多次,给拍错人为的增加难度,既然决定将异常抛出就不要进行日志的输出了,但是如果想保存当前变量的状态仍然是可以的,不过这样做,throw这个异常就显得意义不大了。

点赞
收藏
评论区
推荐文章
kenx kenx
2年前
SpringBoot优雅的全局异常处理
前言在日常项目开发中,异常是常见的,但是如何更高效的处理好异常信息,让我们能快速定位到BUG,是很重要的,不仅能够提高我们的开发效率,还能让你代码看上去更舒服,SpringBoot的项目已经有一定的异常处理了,但是对于我们开发者而言可能就不太合适了,因此我们需要对这些异常进行统一的捕获并处理。SpringBoot默认的错误处理机制返回错误页面默认返回W
Wesley13 Wesley13
2年前
java 8 lambda表达式中的异常处理
java8lambda表达式中的异常处理简介java8中引入了lambda表达式,lambda表达式可以让我们的代码更加简介,业务逻辑更加清晰,但是在lambda表达式中使用的FunctionalInterface并没有很好的处理异常,因为JDK提供的这些FunctionalInterface通常都是没有抛出异常的,这意味着需要我们自
Wesley13 Wesley13
2年前
Java8(5):使用 Optional 处理 null
Java8(5):使用Optional处理null写过Java程序的同学,一般都遇到过NullPointerException:)——为了不抛出这个异常,我们便会写如下的代码:UserusergetUserById(id);if(user!
Wesley13 Wesley13
2年前
03.Android崩溃Crash库之ExceptionHandler分析
目录总结00.异常处理几个常用api01.UncaughtExceptionHandler02.Java线程处理异常分析03.Android中线程处理异常分析04.为何使用setDefaultUncaughtExceptionHandler前沿上一篇整体介绍了crash崩溃
Wesley13 Wesley13
2年前
Java异常处理只有Try
今天,我们将讨论一个非常重要的主题Java中的异常处理。尽管有时可能会对此主题进行过多的讨论,但并非每篇文章都包含有用且相关的信息。Java中最常见的异常处理机制通常与trycatch块关联。我们使用它来捕获异常,然后提供在发生异常的情况下可以执行的逻辑。的确,你不需要将所有异常都放在这些块中。另一方面,如果你正在研究应用程序的软
Wesley13 Wesley13
2年前
JAVA运行时异常及常见的5中RuntimeExecption
java运行时异常是可能在java虚拟机正常工作时抛出的异常。java提供了两种异常机制。一种是运行时异常(RuntimeExepction),一种是检查式异常(checkedexecption)。检查式异常:我们经常遇到的IO异常及sql异常就属于检查式异常。对于这种异常,java编译器要求我们必须对出现的这些异常进行catch所以面对这种异
Easter79 Easter79
2年前
SpringBoot2.0系列教程(五)Springboot框架添加全局异常处理
Hello大家好,本章我们添加全局异常处理。另求各路大神指点,感谢一:为什么需要定义全局异常在互联网时代,我们所开发的应用大多是直面用户的,程序中的任何一点小疏忽都可能导致用户的流失,而程序出现异常往往又是不可避免的,所以我们需要对异常进行捕获,然后给予相应的处理,来减少程序异常对用户体验的影响二:添加业务类异常在前面说过
Stella981 Stella981
2年前
PlayJava Day020
1.异常Exception补充:①错误(Error)指的是致命性错误,一般无法处理②异常以类的形式封装程序可以处理的异常对应的类是java.lang.Exception及其子类运行时异常对应的类是java.lang.RuntimeException错误异常对应的类是java.lang.Error③异常相关类的继承树:java.la
Wesley13 Wesley13
2年前
Java异常架构
Java异常简介Java异常是Java提供的一种识别及响应错误的一致性机制。Java异常机制可以使程序中异常处理代码和正常业务代码分离,保证程序代码更加优雅,并提高程序健壮性。在有效使用异常的情况下,异常能清晰的回答what,where,why这3个问题:异常类型回答了“什么”被抛出,异常堆栈跟踪回答了“在哪“抛出,异常信息
Stella981 Stella981
2年前
SpringBoot2.0系列教程(五)Springboot框架添加全局异常处理
Hello大家好,本章我们添加全局异常处理。另求各路大神指点,感谢一:为什么需要定义全局异常在互联网时代,我们所开发的应用大多是直面用户的,程序中的任何一点小疏忽都可能导致用户的流失,而程序出现异常往往又是不可避免的,所以我们需要对异常进行捕获,然后给予相应的处理,来减少程序异常对用户体验的影响二:添加业务类异常在前面说过