【软件开发规范篇】JAVA后端开发异常处理规范

作者介绍:本人笔名姑苏老陈,从事JAVA开发工作十多年了,带过大学刚毕业的实习生,也带过技术团队。最近有个朋友的表弟,马上要大学毕业了,想从事JAVA开发工作,但不知道从何处入手。于是,产生了写一个博客专栏想法,介绍当前互联网企业JAVA项目开发如何快速入门。

本文收录于《30天企业JAVA项目开发实战入门》专栏,该专栏内容以当前互联网软件企业中的项目实战为线索,介绍企业JAVA项目开发中涉及到的开发流程、技术、工具、规范要求等等。帮助想从事JAVA开发的大学生或新人,更快的、更好的入门JAVA后端开发工作。

文章目录

    • 一、前言
    • 二、关于异常处理的规范
    • 三、总结

一、前言

现在的软件项目都是团队多人合作一起开发,软件架构的复杂性也需要协同开发完成,如何高效地协同呢?

无规矩不成方圆,无规范难以协同。对软件来说,适当的规范和标准绝不是消灭代码内容的创造性、优雅性,而是限制过度个性化,以一种普遍认可的统一方式一起做事,提升协作效率,降低沟通成本。

本文介绍一下JAVA后端开发过程中,关于异常处理,可以遵循的一些工作规范。

在这里插入图片描述

二、关于异常处理的规范

1.【强制】Java 类库中定义的可以通过预检查方式规避的 RuntimeException 异常不应该通过catch 的方式来处理。

比如:NullPointerException,IndexOutOfBoundsException 等等。

说明:无法通过预检查的异常除外,比如,在解析字符串形式的数字时,可能存在数字格式错误,不得不通过 catch NumberFormatException 来实现。

正例:if (obj != null) {...}反例:try { obj.method(); } catch (NullPointerException e) {…}
  1. 【强制】异常不要用来做流程控制,条件控制。

说明:异常设计的初衷是解决程序运行中的各种意外情况,且异常的处理效率比条件判断方式要低很多。

  1. 【强制】catch 时请分清稳定代码和非稳定代码,稳定代码指的是无论如何不会出错的代码。对于非稳定代码的 catch 尽可能进行区分异常类型,再做对应的异常处理。

    说明:对大段代码进行 try-catch,使程序无法根据不同的异常做出正确的应激反应,也不利于定位问题,这是一种不负责任的表现。

    正例:用户注册的场景中,如果用户输入非法字符,或用户名称已存在,或用户输入密码过于简单,在程序上作出分门别类的判断,并提示给用户。

  2. 【强制】捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,请将该异常抛给它的调用者。最外层的业务使用者,必须处理异常,将其转化为用户可以理解的内容。

  3. 【强制】事务场景中,抛出异常被 catch 后,如果需要回滚,一定要注意手动回滚事务。

  4. 【强制】finally 块必须对资源对象、流对象进行关闭,有异常也要做 try-catch。

    说明:如果 JDK7 及以上,可以使用 try-with-resources 方式。

  5. 【强制】不要在 finally 块中使用 return。
    说明:try 块中的 return 语句执行成功后,并不马上返回,而是继续执行 finally 块中的语句,如果此处存
    在 return 语句,则在此直接返回,无情丢弃掉 try 块中的返回点。

反例:
private int x = 0;
public int checkReturn() {
try {
// x 等于 1,此处不返回
return ++x;
} finally {
// 返回的结果是 2
return ++x;
}
}
  1. 【强制】捕获异常与抛异常,必须是完全匹配,或者捕获异常是抛异常的父类。

    说明:如果预期对方抛的是绣球,实际接到的是铅球,就会产生意外情况。

  2. 【强制】在调用 RPC、二方包、或动态生成类的相关方法时,捕捉异常必须使用 Throwable类来进行拦截。

    说明:因为抛出的异常类型,有可能不是Exception类,而是Error类,所以使用Throwable类拦截;

    另外,通过反射机制来调用方法,如果找不到方法,抛出 NoSuchMethodException。什么情况会抛出NoSuchMethodError 呢? 二方包在类冲突时,仲裁机制可能导致引入非预期的版本使类的方法签名不匹配,或者在字节码修改框架(比如:ASM)动态创建 或修改类时,修改了相应的方法签名。这些情况,即使代码编译期是正确的,但在代码运行期时,会抛出 NoSuchMethodError。

10.【推荐】方法的返回值可以为 null,不强制返回空集合,或者空对象等,必须添加注释充分说明什么情况下会返回 null 值。

说明:本手册明确防止 NPE 是调用者的责任。即使被调用方法返回空集合或者空对象,对调用者来说,也并非高枕无忧,必须考虑到远程调用失败、序列化失败、运行时异常等场景返回 null 的情况。

11.【推荐】防止 NPE,是程序员的基本修养,注意 NPE 产生的场景:
1) 返回类型为基本数据类型,return 包装数据类型的对象时,自动拆箱有可能产生 NPE。
反例:public int f() { return Integer 对象}, 如果为 null,自动解箱抛 NPE。
2) 数据库的查询结果可能为 null。备注:千万不要认为count方法,一定会返回数量值,没有的话就一定会返回0,注意可能会返回null。
3) 集合里的元素即使 isNotEmpty,取出的数据元素也可能为 null。
4) 远程调用返回对象时,一律要求进行空指针判断,防止 NPE。
5) 对于 Session 中获取的数据,建议进行 NPE 检查,避免空指针。
6) 级联调用 obj.getA().getB().getC();一连串调用,易产生 NPE。

正例:使用 JDK8 的 Optional 类来防止 NPE 问题。

说明:Optional 主要用作返回类型。在获取到这个类型的实例后,如果它有值,你可以取得这个值,否则可以进行一些替代行为。
Optional 类有一个非常有用的用例,就是将其与流或其它返回 Optional 的方法结合,以构建流畅的API。

我们来看一个示例,使用 Stream 返回 Optional 对象的 findFirst() 方法:

@Test
public void whenEmptyStream_thenReturnDefaultOptional() {List<User> users = new ArrayList<>();User user = users.stream().findFirst().orElse(new User("default", "1234"));assertEquals(user.getEmail(), "default");}

12.【推荐】定义时区分 unchecked / checked 异常,避免直接抛出 new RuntimeException(),更不允许抛出 Exception 或者 Throwable,应使用有业务含义的自定义异常。

推荐业界已定义过的自定义异常,如:DAOException / ServiceException\CustomException 等。

13.【参考】对于公司外的 http/api 开放接口必须使用“错误码”;而应用内部推荐异常抛出;跨应用间 RPC 调用优先考虑使用 Result 方式,封装 isSuccess()方法、“错误码”、“错误简短信息”;而应用内部推荐异常抛出。

说明:关于 RPC 方法返回方式使用 Result 方式的理由:
1)使用抛异常返回方式,调用方如果没有捕获到就会产生运行时错误。
2)如果不加栈信息,只是 new 自定义异常,加入自己的理解的 error message,对于调用端解决问题的帮助不会太多。如果加了栈信息,在频繁调用出错的情况下,数据序列化和传输的性能损耗也是问题。

14.【参考】如果外部服务基本不可用,而我们又同步调用外部服务的话,我们需要进行自我保护直接熔断,否则在持续的并发的情况下自己就会垮了;

如果外部服务特别重要,我们往往会考虑引入多个同类型的服务,根据价格、服务标准做路由,在出现问题的时候自动降级。

推荐使用Netflix开源的hystrix容灾框架,主要解决当外部依赖出现故障时拖垮业务系统、甚至引起雪崩的问题。

三、总结

以上介绍了软件项目开发中,JAVA异常处理,可以遵循的一些规范。

在JAVA编程中,异常处理是非常重要的一部分。异常是指程序在运行时出现的错误或意外情况,例如除以零、数组越界、空指针引用等。如果没有进行异常处理或者处理得不规范,程序将会崩溃或者产生不可预知的结果,给用户带来极大的不便和安全隐患。

附本文参考资料:

  • 阿里云官方知乎:https://www.zhihu.com/org/a-li-yun-97-77
  • 阿里云开发者官方社区:https://developer.aliyun.com/
  • 阿里开发者官方CSDN社区:https://blog.csdn.net/alitech2017?type=blog
  • 阿里云云栖号CSDN:https://blog.csdn.net/yunqiinsight/category_10231626.html
  • 阿里巴巴技术团队发布的《JAVA开发手册》泰山版
  • 阿里云开发者官方微信公众号

如果您对文章中内容有疑问,欢迎在评论区进行留言,我会尽量抽时间给您回复。如果文章对您有帮助,欢迎点赞、收藏。您的点赞,是对我最大的支持和鼓励,谢谢 :-)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1411024.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

01 Activiti 7:步骤

01 Activiti 7&#xff1a;步骤 1. 整合Activiti2. 业务流程建模3. 部署业务流程4. 启动流程实例5. 查询待办任务6. 处理待办任务7. 结束流程 1. 整合Activiti 业务系统使用 Activiti 来对系统的业务流程进行自动化管理。为了方便业务系统访问&#xff08;操作&#xff09;Act…

C语言 循环语句 (3) for 循环语句

接下来 我们来看第三个 for语句 基本语句是 for关键字 然后小括号 括号中三个表达式 然后它对表达式2进行判断 如果表达式2条件成立 则走进循环体 执行完循环体 会回来执行表达式3 然后再返回来 继续对表达式2进行判断 如果表达式2 还是成立 这继续循环往复 直到表达式2的条件…

《Fundamentals of Power Electronics》——隔离型CUK转换器、

以下是隔离型CUK转换器的相关知识点&#xff1a; Cuk电路的隔离型版本获得方式不同。基础非隔离型Cuk电路如下图所示。 将上图中电容C1分成两个串联的电容C1a和C1b&#xff0c;得到结果如下图所示。 在两个电容之间插入一个变压器&#xff0c;得到如下图所示电路。 变压器极性…

可视化大屏应用场景:智慧安防,保驾护航

hello&#xff0c;我是大千UI工场&#xff0c;本篇分享智慧安防的大屏设计&#xff0c;关注我们&#xff0c;学习N多UI干货&#xff0c;有设计需求&#xff0c;我们也可以接单。 实时监控与预警 可视化大屏可以将安防系统中的监控画面、报警信息、传感器数据等实时展示在大屏上…

Java毕业设计 基于SSM SpringBoot vue宠物领养平台

Java毕业设计 基于SSM SpringBoot vue宠物领养平台 SSM 宠物领养平台 功能介绍 首页 图片轮播 新闻信息 新闻类型 新闻详情 宠物百科 宠物百科类型 宠物百科详情 宠物 宠物类型 宠物详情 立即领养 留言 论坛 发布帖子 登录 个人中心 宠物收藏 宠物领养订单 后台管理 登录注…

ssm104园区停车管理系统+jsp

园区停车管理系统的设计与实现 摘 要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#xff0c;尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代&#xff0c;所以对于信息的宣传和管…

链表面试题及其解析

1.返回倒数第k个节点 实现一种算法&#xff0c;找出单向链表中倒数第 k 个节点。返回该节点的值。 示例&#xff1a; 输入&#xff1a; 1->2->3->4->5 和 k 2 输出&#xff1a; 4 说明&#xff1a; 给定的 k 保证是有效的。 1.1快慢指针 即慢指针一次走一步…

关于Windows登录密码的思考题

1. windows登录的明文密码&#xff0c;存储过程是怎么样的&#xff0c;密文存在哪个文件下&#xff0c;该文件是否可以打开&#xff0c;并且查看到密文 在Windows系统中&#xff0c;密码通常以哈希值的形式存储在注册表中的SAM文件中。SAM文件位于C:\Windows\System32\config\S…

简化Transformer模型,以更少的参数实现更快的训练速度

在深度学习领域&#xff0c;Transformer模型因其卓越的性能而广受欢迎&#xff0c;但其复杂的架构也带来了训练时间长和参数数量多的挑战。ETH Zurich的研究人员Bobby He和Thomas Hofmann在最新研究中提出了一种简化的Transformer模型&#xff0c;通过移除一些非必要的组件&…

FP16、BF16、INT8、INT4精度模型加载所需显存以及硬件适配的分析

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

基于SSM SpringBoot vue宾馆网上预订综合业务服务系统

基于SSM SpringBoot vue宾馆网上预订综合业务服务系统 系统功能 首页 图片轮播 宾馆信息 饮食美食 休闲娱乐 新闻资讯 论坛 留言板 登录注册 个人中心 后台管理 登录注册 个人中心 用户管理 客房登记管理 客房调整管理 休闲娱乐管理 类型信息管理 论坛管理 系统管理 新闻资讯…

文心一言 VS 讯飞星火 VS chatgpt (251)-- 算法导论18.2 4题

四、假设关键字 {1&#xff0c;2&#xff0c;…&#xff0c;n} 被插入一棵最小度数为 2 的空 B 树中&#xff0c;那么最终的B树有多少个结点&#xff1f;如果要写代码&#xff0c;请用go语言。 文心一言&#xff1a; B树&#xff08;B-tree&#xff09;是一种自平衡的树&…

2024年钉钉群直播回放如何永久保存

工具我已经打包好了&#xff0c;有需要的自己取一下 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;1234 --来自百度网盘超级会员V10的分享 1.首先解压好我给大家准备好的压缩包 2.再把逍遥一仙下载器压缩包也解压一下 3.打开逍遥一仙下载器文件夹里面的M3U8…

2022蓝桥杯国赛

题目描述&#xff1a; 思路&#xff1a; 题主用了两个方法&#xff0c;一个是三维数组&#xff0c;1到2022个数可以当成编号&#xff0c;f[i][j][k]表示前i个数选了j个数总和为k&#xff0c;存在是否选择第i个数的问题&#xff0c;选择第i个数为f[i-1][j-1][k-i];没有选择第i个…

计算机网络实验——学习记录六(TCP协议流量控制分析)

1. nc -d 5 -lv 4499 > 10K.1 其中&#xff1a; &#xff08;1&#xff09;-d 5 表示建立连接之后&#xff0c;延迟5秒再读取数据&#xff1b; &#xff08;2&#xff09;> 10K.1 表示将输出重定向到文件10K.1中&#xff1b; 2. 零窗口通知报文 3. 窗口探测报文

Gitea 上传用户签名

在 Gitea 的用户管理部分&#xff0c;有一个 SSH 和 GPG 的选项。 单击这个选项&#xff0c;可以在选项上添加 Key。 Key 的来源 如是 Windows 的用户&#xff0c;可以选择 Kleopatra 这个软件。 通过这个软件生成的 Key 的界面中有一个导出功能。 单击这个导出&#xff0c;…

Redis 实战3

系列文章目录 本文将从跳跃表的实现、整数集合来展开 Redis 实战 Ⅲ 系列文章目录跳跃表的实现跳跃表节点层 前进指针跨度 整数集合的实现升级升级的好处提升灵活性节约内存 降级整数集合 API总结 跳跃表的实现 Redis 的跳跃表由 redis.h/zskiplistNode 和 redis.h/zskiplist…

nginx--压缩https证书favicon.iconginx隐藏版本号 去掉nginxopenSSL

压缩功能 简介 Nginx⽀持对指定类型的⽂件进行压缩然后再传输给客户端&#xff0c;而且压缩还可以设置压缩比例&#xff0c;压缩后的文件大小将比源文件显著变小&#xff0c;这样有助于降低出口带宽的利用率&#xff0c;降低企业的IT支出&#xff0c;不过会占用相应的CPU资源…

FreeRTOS学习——FreeR TOS队列(下)

本篇文章记录我学习FreeRTOS的队列的相关知识&#xff0c;在此记录分享一下&#xff0c;希望我的分享对你有所帮助。 FreeRTOS学习——FreeRTOS队列&#xff08;上&#xff09;-CSDN博客 一、FreeRTOS队列的创建 &#xff08;一&#xff09;、函数原型 在使用队列之前必须先创…

【Linux 系统】进程信号 -- 详解

⚪前言 注意&#xff1a;进程间通信中的信号量跟下面要讲的信号没有任何关系。 一、从不同角度理解信号 1、生活角度的信号 你在网上买了很多件商品&#xff0c;在等待不同商品快递的到来。但即便快递没有到来&#xff0c;你也知道快递来临时&#xff0c;你该怎么处理快递&a…