前言

不管在我们的工作还是生活中,总会出现各种“错误”,各种突发的“异常”。无论我们做了多少准备,多少测试,这些异常总会在某个时间点出现,如果处理不当或是不及时,往往还会导致其他新的问题出现。所以我们要时刻注意这些陷阱以及需要一套“最佳实践”来建立起一个完善的异常处理机制。

正文

异常分类

首先,这里我画了一个异常分类的结构图。

在JDK中,Throwable是所有异常的父类,其下分为”Error“和”Exception“。Error意味着出现了不可控的严重错误,例如OutOfMemoryError。Exception则细分为两类,受检异常(check)需要我们手动try/catch或者在方法定义中throws,编译器在编译的时候会检查其合法性。非受检异常(uncheck)则不需要我们提前处理。这些简单的概念对于开发人员来说都是必须掌握的,这里就展示个图例,不做详细的描述了,我们的”正餐“还在后面。

重新认识try/catch/finally

说到异常处理,这里就不得不提try/catch/finally。try不可以单独存在,要么搭配catch,要么搭配finally,或者三者并存。
1、try代码块:监视代码块的执行,发现对应的的异常则跳转至catch,若无catch则直接到finally块。
2、catch代码块:发生对应的异常会执行里面的代码,要么处理,要么向上抛出。
3、finally代码块:不管是否有异常,都必执行,一般用来清理资源,释放连接等。然而有以下几种情况不会执行到这里的代码。

  • 代码执行流程未进入try代码块。
  • 代码在try代码块中发生死循环、死锁等状态。
  • 在try代码块中执行了System.exit()操作。
try/catch/finally陷阱

下面介绍两个我们在使用tcf的时候可能会遇到的陷阱。

代码1

public class TCFDemo {
public static void main(String[] args) {
//
System.out.println(returnVal());
} static int returnVal(){
int a = 1;
int b = 10;
try{
return ++a;
}finally {
return ++b;
}
}
}

陷阱1:在finally中添加return语句,这样会覆盖掉try代码return的值,假如业务逻辑比较复杂,这里是很容易掉坑的,不利于排查错误。

代码2

public class TCFDemo {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
try{
//有可能加锁失败
lock.lock();
//dost
}finally {
lock.unlock();
}
}
}

陷阱2:由于lock方法在加锁的时候有可能会抛出Uncheck异常,如果在try代码块中,必然会执行unlock方法,此时由于并没有加锁成功,所以会抛出IllegalMonitorStateException,这样一来后者的异常就覆盖掉了前者加锁失败的异常信息,所以我们应该把加锁的方法挪至try代码块外面。

最佳实践

好了,前面简单介绍了异常的分类以及try/catch/finally的注意事项,现在可以总结一下我们在异常处理的时候有哪些”最佳实践“了。

  1. 当需要向上抛出异常的时候,需根据当前业务场景定义具有业务含义的异常,优先使用行业内定义的异常或者团队内部定义好的。例如在使用dubbo进行远程服务调用超时的时候会抛出DubboTimeoutException,而不是直接把RuntimeException抛出。
  2. 请勿在finally代码块中使用return语句,避免返回值的判断变得复杂。
  3. 捕获异常具体的子类,而不是Exception,更不是throwable。这样会捕获所有的错误,包括JVM抛出的无法处理的严重错误。
  4. 切记更别忽视任何一个异常(catch住了不做任何处理),即使现在能确保不影响逻辑的正常运行,但是对于将来谁都无法保证代码会如何改动,别给自己挖坑。
  5. 不要使用异常当作控制流程来使用,这是一个很奇葩也很影响性能的做法。
  6. 清理资源,释放连接等操作一定要放在finally代码块中,防止内存泄漏,如果finally块处理的逻辑比较多且模块化,我们可以封装成工具方法调用,代码会比较简洁。

结尾

小小的异常,有大大的学问,你觉得呢?

公众号《深夜里的程序猿》 - 分享最干的干货

Java异常处理最佳实践及陷阱防范的更多相关文章

  1. Java异常处理最佳实践

    总结一些Java异常的处理原则 Java异常处理最佳实践 不要忘记关闭资源 在finally里关闭资源 public void readFile() { FileInputStream fileInp ...

  2. 最重要的 Java EE 最佳实践

    參考:IBM WebSphere 开发人员技术期刊: 最重要的 Java EE 最佳实践 IBM WebSphere 开发人员技术期刊: 最重要的 Java EE 最佳实践 2004 年 IBM® W ...

  3. paip.myeclipse7 java webservice 最佳实践o228

    paip.myeclipse7  java webservice 最佳实践o228 java的ws实现方案:jax-ws>>xfire ws的测试工具  webservice测试调用工具W ...

  4. 10个精妙的Java编码最佳实践

    这是一个比Josh Bloch的Effective Java规则更精妙的10条Java编码实践的列表.和Josh Bloch的列表容易学习并且关注日常情况相比,这个列表将包含涉及API/SPI设计中不 ...

  5. 你知道吗?10个精妙的 Java 编码最佳实践

    这是一个比Josh Bloch的Effective Java规则更精妙的10条Java编码实践的列表.和Josh Bloch的列表容易学习并且关注日常情况相比,这个列表将包含涉及API/SPI设计中不 ...

  6. Atitit.嵌入式web 服务器 java android最佳实践

    Atitit.嵌入式web 服务器 java android最佳实践 1. Android4.4.21 2. 自己的webserver1 3. CyberHTTP for Java  cybergar ...

  7. SpringBoot系列: Spring项目异常处理最佳实践

    ===================================自定义异常类===================================稍具规模的项目, 一般都要自定义一组异常类, 这 ...

  8. Java开发最佳实践(二) ——《Java开发手册》之"异常处理、MySQL 数据库"

    二.异常日志 (一) 异常处理 (二) 日志规约 三.单元测试 四.安全规约 五.MySQL数据库 (一) 建表规约 (二) 索引规约 (三) SQL语句 (四) ORM映射 六.工程结构 七.设计规 ...

  9. [转]java的异常处理最佳实践

    本文转载自 Karibasappa G C (KB), the Founder of javainsimpleway.com, 原文链接 http://javainsimpleway.com/exce ...

随机推荐

  1. Centos7下安装MySql

    1.安装MariaDB 安装命令 yum -y install mariadb mariadb-server 安装完成MariaDB,首先启动MariaDB systemctl start maria ...

  2. LinkedList源码

    1.介绍及注意事项 链表由Josh Bloch书写,属于Java集合框架中的一种,LinkedList实现的是双链表,实现了所有的链表操作,可能够实现所有元素(包括)的基本操作. 链表是非线程同步的, ...

  3. python new和init知识点

    __new__ 方法是什么?如果将类比喻为工厂,那么__init__()方法则是该工厂的生产工人,__init__()方法接受的初始化参 数则是生产所需原料,__init__()方法会按照方法中的语句 ...

  4. Web开发环境搭建 Eclipse-Java EE 篇

    Web开发环境搭建 Eclipse-Java EE 篇 [原创内容,转载注名出处] 1. 下载和安装 1.1 下载JDK 在Java官方网站下载最新版本的 Java SE:  http://www.o ...

  5. spring中注解式事务不生效的问题

    常用的解决方法可以百度,我针对我的问题描述一下 Mysql中InnoDB引擎才支持事务, MyISAM不支持事务. 当你尝试了各种方法解决spring中注解式事务不生效时, 一定要查看一下数据库中表的 ...

  6. jenkins在windows下的最快安装方法

    jenkins在windows下的安装 2016年04月21日 13:00:09 阅读数:22828 在初步了解了jenkins是什么?jenkins的特点.基本结构,及大概的功能介绍后,就开始对je ...

  7. 解决WordPress用户名密码都正确但点击登陆就清空密码的问题

    作者:荒原之梦 问题产生的环境与问题描述: 今天我在浏览器的书签里将我保存的用于登陆WordPress的书签名字改了一下,之后再登陆WordPress就出现提示说Cookies被阻止,要启用Cooki ...

  8. C# 读取XML节点属性值

    xml文件格式如下: <?xml version="1.0" encoding="UTF-8" ?> <Product type=" ...

  9. Android 5.x Theme 与 ToolBar 实战

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/45303349: 本文出自:[张鸿洋的博客] 1.概述 随着Material D ...

  10. bash: jar: 未找到命令..(command not found)

    /bin/bash: jar: command not found 解决办法: cd /usr/bin 必须先进入/usr/bin,下同 sudo ln -s -f /usr/lib/jvm/jdk1 ...