网站首页 > 精选教程 正文
1. 不要使用异常来控制业务逻辑
在开发具体业务时,很多人会使用异常来控制业务逻辑,例如:
try{
execute();
}catch(Exception e){
execute1();
}catch(Exception1 e1){
execute2();
}
代码中的分支逻辑应该使用if-else来控制,而不是依赖异常。使用异常来控制代码逻辑不容易理解,难于维护。
2. 如果处理不了,请不要捕获
很多人在开发中,遇到try语句块,后面一定会跟一个catch块,这是不对的。我们在开发中,应该只捕获那些能处理的异常,如果处理不了,就不要捕获它,继续向上抛,谁能解决谁来捕获。
像下面这段代码对于异常的处理就毫无意义:
try{
}catch (Exception e){
throw e;
}
3. 在catch 语句中不要使用printStackTrace()
由于现在的开发工具IDE都比较智能,当我们在写一段try-catch代码时,通常会自动生成printStackTrace()语句,例如:
try{
execute();
}catch (Exception e){
e.printStackTrace();
}
需要注意的是,e.printStackTrace()并不是处理异常,很多人认为这是在打印异常信息,也是在处理异常。
但是,e.printStackTrace()表示把异常信息输出到控制台,而不是日志中。e.printStackTrace()只能在调试阶段使用,程序在线上运行时,错误的信息要通过日志输出。
4. 二次抛出异常时,要带上异常链
我们在处理异常时,有时可能会先捕获一个异常,再抛出另一个异常。这种场景一般用于抛出一些特定的、更容易理解的业务异常。
这样做是可以的,但在抛出新的异常时,一定要把被捕获的那个异常的异常信息也带上,避免丢失异常的堆栈。例如:
try{
}catch (Exception e){
// 错误用法
throw new MyException();
// 正确用法
throw new MyException(e);
}
5. 在需要的地方声明特定的受检异常
受检异常的最大特点是要求调用者必须明确地处理这个异常,这其实是一种强制性的约束。所以,当代码中有一些特殊情况需要让调用者必须关注时,要使用受检异常,起到提醒的作用。
6. 异常捕获的顺序需要特殊注意
很多人知道异常需要处理,并且尝试在代码中捕获异常,因为可能有很多异常抛出,所以会同时捕获多个异常,于是有人就写出了以下代码:
try{
}catch (Exception e){
}catch (MyException e){
}catch (IllegalArgumentException e){
}
以上处理方式最大的问题就是异常的捕获顺序不合理,以上形式的捕获异常,后面的MyException和IllegalArgumentException永远不会被捕获,异常一旦发生就会被Exception直接捕获了。
所以,在捕获异常时,要把范围较小的异常放到前面,对于RuntimeException、Exception和Throwable的捕获一定要放到最后。
7. 可以直接捕获Exception,但是要注意场景
在关于异常的处理上,很多人建议不要直接对Exception、Throwable进行捕获,因为捕获的范围太大了,会导致永远无法知道异常的具体细节。
其实有时我们可能还真的需要对Exception、甚至Throwable进行捕获,尤其是现在很多应用都微服务化了,经常会有各种RPC接口的互相调用。
我们在给外部提供一个RPC接口时,应该通过错误码的形式传递错误信息,而不是把异常抛给调用方。因为A系统的异常抛给B系统,B系统是一定处理不了的。
所以,我们往往需要在RPC接口中对Exception进行捕获,以避免异常交给外部系统。
8. 可以直接捕获Throwable,但是要注意场景
Throwable有Error和Exception两个子类,通常我们认为Error是程序员处理不了的,所以不建议捕获。
但是有一种特殊的情况,我们可能需要捕获Error。
当我们提供RPC服务时,一旦服务被调用过程中发生了Error,如NoSuchMethodError,我们没有捕获,那么这个错误就会一直往上抛,最终被RPC框架捕获。
RPC框架捕获这个错误之后,可能会把错误日志打印到它自己的日志文件中,而不是我们应用的业务日志中。
通常RPC框架自己的日志会有很多各种超时等异常,我们很少对其进行错误监控,这就可能导致错误发生了,但我们无法察觉。
9. 不要在finally 中抛出异常
示例代码如下:
try {
execute();
}finally
{
throw new Exception();
}
当execute方法抛出异常之后,我们在finally中再次抛出一个异常,这就导致execute方法抛出的那个异常信息完全丢失了。丢失了异常链,会给后期的问题排查带来很大的困难。
10. 在finally 中释放资源
当我们想要释放一些资源时,如数据库链接、文件链接等,需要在finally中进行释放,因为finally中的代码一定会执行。
11. 如果不想处理异常,则使用finally 块而不是catch 块
因为我们要在finally中释放资源,所以很多开发者会顺手把try-catch-finally都写上,这其实是错误的。
当我们不想处理一个异常,又想在异常发生后做一些事情的时候,不要写catch块,而是使用finally块。
12. 善于使用自定义异常
我们在日常开发中会接触很多异常,JDK内置了很多异常,一些框架中也定义了自己的异常。我们也可以自定义一些业务异常,这些异常可以有一定的继承关系,方便我们快速地识别异常的原因,以及快速恢复。比如OrderCanceledException、LoginFailedException等,我们通过这些异常的名字就知道具体发生了什么。
13. try 块中的代码要尽可能的少
不要在一个几百行代码外面加一个try进行异常处理,我们需要控制try的粒度,对于那些明显不会发生异常的代码,就不要把它们放到try块中。
内容摘自《深入理解Java核心技术》,作者是Hollis,张洪亮,阿里巴巴技术专家,51CTO 专栏作家,CSDN 博客专家,掘金优秀作者,《程序员的三门课》联合作者,《Java工程师成神之路》系列文章作者;热衷于分享计算机编程相关技术,博文全网阅读量数千万。
- 上一篇: 三十七、Java异常处理
- 下一篇: Java提高篇——Java 异常处理
猜你喜欢
- 2024-11-20 Java中的异常
- 2024-11-20 小白也能看懂的Java异常处理机制
- 2024-11-20 JVM是如何处理各种异常的呢?
- 2024-11-20 Java异常之异常处理类详解和代码举例
- 2024-11-20 第25天|Java入门有野,异常处理
- 2024-11-20 java安全编码指南之:异常处理
- 2024-11-20 解读Java编程思想--异常处理
- 2024-11-20 Java中异常处理机制的详细解析及其优化示例代码
- 2024-11-20 学习java, 需要知道的异常处理
- 2024-11-20 java异常处理
你 发表评论:
欢迎- 04-11Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- 04-11Java中你知道几种从字符串中找指定的字符的数量
- 04-11探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- 04-11Python字符串详解与示例(python字符串的常见操作)
- 04-11java正则-取出指定字符串之间的内容
- 04-11String s1 = new String("abc");这句话创建了几个字符串对象?
- 04-11java判断字符串中是否包含某个字符
- 04-11关于java开发中正确的发牌逻辑编写规范
- 最近发表
-
- Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- Java中你知道几种从字符串中找指定的字符的数量
- 探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- Python字符串详解与示例(python字符串的常见操作)
- java正则-取出指定字符串之间的内容
- String s1 = new String("abc");这句话创建了几个字符串对象?
- java判断字符串中是否包含某个字符
- 关于java开发中正确的发牌逻辑编写规范
- windows、linux如何后台运行jar(并且显示进程名)
- 腾讯大佬私人收藏,GitHub上最受欢迎的100个JAVA库,值得学习
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)