Java异常处理的最佳实践

Wesley13
• 阅读 126

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这个异常就显得意义不大了。

点赞
收藏
评论区
推荐文章
光头强的博客 光头强的博客
2个月前
Java面向对象试题
1、 请创建一个Animal动物类,要求有方法eat()方法,方法输出一条语句“吃东西”。 创建一个接口A,接口里有一个抽象方法fly()。创建一个Bird类继承Animal类并实现 接口A里的方法输出一条有语句“鸟儿飞翔”,重写eat()方法输出一条语句“鸟儿 吃虫”。在Test类中向上转型创建b对象,调用eat方法。然后向下转型调用eat()方
Wesley13 Wesley13
1年前
java 8 lambda表达式中的异常处理
java 8 lambda表达式中的异常处理 简介 == java 8中引入了lambda表达式,lambda表达式可以让我们的代码更加简介,业务逻辑更加清晰,但是在lambda表达式中使用的Functional Interface并没有很好的处理异常,因为JDK提供的这些Functional Interface通常都是没有抛出异常的,这意味着需要我们自
Stella981 Stella981
1年前
Spring Cloud Gateway 全局通用异常处理
为什么需要全局异常处理 ----------- 在传统 Spring Boot 应用中, 我们 @ControllerAdvice 来处理全局的异常,进行统一包装返回 // 摘至 spring cloud alibaba console 模块处理 @ControllerAdvice public class Consol
Wesley13 Wesley13
1年前
Java8(5):使用 Optional 处理 null
Java8(5):使用 Optional 处理 null ============================ 写过 Java 程序的同学,一般都遇到过 `NullPointerException` :) —— 为了不抛出这个异常,我们便会写如下的代码: User user = getUserById(id); if (user !=
Wesley13 Wesley13
1年前
03.Android崩溃Crash库之ExceptionHandler分析
#### 目录总结 * 00.异常处理几个常用api * 01.UncaughtExceptionHandler * 02.Java线程处理异常分析 * 03.Android中线程处理异常分析 * 04.为何使用setDefaultUncaughtExceptionHandler ### 前沿 * 上一篇整体介绍了crash崩溃
Wesley13 Wesley13
1年前
C++ STL——异常
\[TOC\] * * * _<font color="red">注:原创不易,转载请务必注明原作者和出处,感谢支持!</font>_ _<font color="red">注:内容来自某培训课程,不一定完全正确!</font>_ 一 C++异常机制概述 ----------- 什么是异常处理?一句话,异常处理就是处理程序中的错误。 为什么需要异
Wesley13 Wesley13
1年前
初探 Objective
> 作者: Cyandev, iOS 和 MacOS 开发者,目前就职于字节跳动 ### 0x00 前言 异常处理是许多高级语言都具有的特性,它可以直接中断当前函数并将控制权转交给能够处理异常的函数。不同语言在异常处理的实现上各不相同,本文主要来分析一下 Objective-C 和 C++ 这两个语言。 为什么要把 Objective-C 和
Wesley13 Wesley13
1年前
java Exception和Error的区别
Exception 子类下面的另一部分子类对应于Java程序中的非运行时异常的处理,这些异常也称为显式异常。它们都是在程序中用语句抛出、并且也是用语句进行捕获的,比如,文件没找到引起的异常、类没找到引起的异常等。 常见的异常有: * ArithmeticException——由于除数为0引起的异常; * ArrayStoreExcept
Wesley13 Wesley13
1年前
PostgreSQL疑难问题分析步骤
运维管理postgresql 时难免不会遇到一些疑难问题,遇到这里问题时怎么处理呢。 一、分析是整库异常还是个别进程异常 ================= 二、首先收集信息 ======== 确认好异常类别后,可以进行收集相应的信息了 整库异常 ---- 1.    检查server状态 执行pg\_ctl status \[-D datad
Stella981 Stella981
1年前
SpringBoot过滤器中的异常处理
在昨天的文章我跟大家分享了SpringBoot中异常的处理中,我说了一个需要注意的点,就是过滤器中抛出的异常无法被异常处理类捕获,然后这个朋友就问应该如何处理。 其实处理这种问题的处理方式有好几种,那么我就简单分享一下我近期一个项目中的处理方式。 Filter中的异常处理思路 -------------- 首先我们要明白,在过滤器中我们一般是不会写很长
Wesley13 Wesley13
1年前
Java 异常处理
> 完善的异常处理有利于程序稳定。不要不停的 catch 异常。 * * * ### 什么是异常?? 定义: 异常是一个事件,它发生在程序的执行过程中,会破坏程序的正常执行 在一个错误发生会在一个方法时,创建一个Exception对象来处理来保证程序能继续执行下去。当异常发生时,JVM会搜索调用栈上的所有方法,若没有找到合适的异常处理方法,JVM将会终