浅析自定义异常为什么是继承RuntimeException类以及RuntimeException、Exception两种异常的用途
在接口开发的过程中,为了程序的健壮性,经常要考虑到代码执行的异常,并给前端一个友好的展示,这里就得用到自定义异常,继承RuntimeException类。那么这个RuntimeException和普通的Exception有什么区别呢。
1、Exception: 非运行时异常,在项目运行之前必须处理掉。一般由程序员try catch 掉。
2、RuntimeException,运行时异常,在项目运行之后出错则直接中止运行,异常由JVM虚拟机处理。
在接口的逻辑判断出现异常时,可能会影响后面代码。或者说绝对不容忍(允许)该代码块出错,那么我们就用RuntimeException,但是我们又不能因为系统挂掉,只在后台抛出异常而不给前端返回友好的提示吧,至少给前端返回出现异常的原因。因此接口的自定义异常作用就体现出来了。
由于项目中自定义异常一般继承 RuntimeException 所以想了解一下为什么。
一、异常基础知识
关于异常基础知识详见之前这篇博客:Java异常处理基础知识笔记:异常处理机制、异常继承关系、捕获异常、抛出异常、异常的传播、异常调用栈、自定义异常、第三方日志库
二、runtimeException和exception的两种异常的用途
网上摘得一段话,比喻的很恰当:
继承Exception还是继承RuntimeException是由异常本身的特点决定的,而不是由是否是自定义的异常决定的。
例如我要写一个java api,这个api中会调用一个极其操蛋的远端服务,这个远端服务经常超时和不可用。所以我决定以抛出自定义异常的形式向所有调用这个api的开发人员周知这一操蛋的现实,让他们在调用这个api时务必考虑到远端服务不可用时应该执行的补偿逻辑(比如尝试调用另一个api)。此时自定义的异常类就应继承Exception,这样其他开发人员在调用这个api时就会收到编译器大大的红色报错:【你没处理这个异常!】,强迫他们处理。
又如,我要写另一个api,这个api会访问一个非常非常稳定的远端服务,除非有人把远端服务的机房炸了,否则这个服务不会出现不可用的情况。而且即便万一这种情况发生了,api的调用者除了记录和提示错误之外也没有别的事情好做。但出于某种不可描述的蛋疼原因,我还是决定要定义一个异常对象描述“机房被炸”这一情况,那么此时定义的异常类就应继承RuntimeException,因为我的api的调用者们没必要了解这一细微的细节,把这一异常交给统一的异常处理层去处理就好了。
总结一下:
抛出 RuntimeException(运行期才可以发现的异常),调用方法的程序员不需要知道会出这个异常。
抛出Exception的方法,调用者需要明确知道这个方法里会出现什么异常,并提示调用者要去处理这个可能得异常。
简单的说,非RuntimeException必要自己写catch块处理掉。RuntimeException不用try catch捕捉将会导致程序运行中断,若用则不会中断。
三、自定义异常代码示例
1、直接返回RuntimeException异常消息
if (StringUtils.isBlank(assignee)) {
throw new RuntimeException("注册表中未查到用户手机号");
}
2、继承RuntimeException类自定义异常
package com.opengauss.exam.common.exception;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.http.HttpStatus;
@EqualsAndHashCode(callSuper = true)
@Data
public class ExamCustomException extends RuntimeException {
//异常信息
private String message;
private String code;
private HttpStatus status;
private Object data;
public ExamCustomException(String message) {
super(message);
this.message = message;
}
public ExamCustomException(String message, String code) {
super(message);
this.message = message;
this.code = code;
}
public ExamCustomException(String message, HttpStatus status) {
super(message);
this.message = message;
this.status = status;
}
public ExamCustomException(String message, Object data) {
super(message);
this.message = message;
this.data = data;
}
}
3、使用自定义异常示例
//获取用户身份信息
CertifiedUser certifiedUser = this.currentUser();
if (null == certifiedUser) {
throw new ExamCustomException("用户信息获取失败");
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
2019-06-19 html转为图片插件:html2canvas保存图片模糊问题解决
2018-06-19 浅析css方面的渲染优化:拆分样式表根据媒体查询加载对应样式表、禁止@import包含依赖链、如何异步加载css
2018-06-19 浅析css动画知识:用法介绍(规则与关键帧)animation-delay为负值提前进行动画、动画函数(三次贝塞尔曲线与步骤缓动函数)补间动画与逐帧动画效果、如何控制动画运行或暂停及控制元素各阶段状态、动画循环次数与方向
2018-06-19 Vue的实例属性和方法
2017-06-19 浅析uniapp开发微信小程序实际问题:预览及真机调试时包超过2M时、uniapp解决输入框被软键盘覆盖的问题、微信小程序flex:1属性不生效无法撑满元素问题、长按识别二维码、uni-app开发微信小程序唤起订阅消息
2017-06-19 获取字符串中出现次数最多的字符
2017-06-19 浏览器工作原理:浅析从输入URL到页面展示这中间发生了什么