《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 http://dzone.com/articles/good-exception-handling 「唐尤华」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

像冠军一样处理异常。

哦,请不要这样写……

// 写一句注释跳过异常
try {
throw new IOException("Made up");
} catch (IOException e) {
// 跳过
}
// 记到日志里,继续处理
try {
throw new IOException("Made up");
} catch (IOException e) {
log.error("blah blah blah", e);
}
// 标记 TODO,不做任何处理
try {
throw new IOException("Made up");
} catch (IOException e) {
// TODO - 处理异常 (;
}

我在各种项目中发现了这种 catch 语句。这是一种“好办法”,可以在短期内掩盖问题。然而几周或几个月后,这些代码将成为开发人员的噩梦。 绝大多数人可不想读日志查问题。 因此,还是让我们避免这种情况。

规则一:catch 语句是用来处理异常的,把异常记到日志里然后继续执行不算处理。唯一的例外是,在发生异常后关闭资源(本文不讨论这种情况;如果感兴趣,可以参考这篇 McDowell 的博客,虽然写的时间比较早,但内容很不错)。

有三种处理异常的基本模式:转换(translate)重试(retry)恢复(recover)

转换经常用于处理受检异常(checked exception),在方法中异常无法抛出,并且无法恢复时使用。 在这种情况下,将其转换为运行时异常(runtime exception)而后抛出是最合适的做法。接下来,运行时异常通常由框架处理。 在处理不可靠的服务时,重试非常有用,前提是重新尝试有意义。一个很好的例子就是网络中断重试。如果定义了这种策略,那么就能够恢复到正常状态。例如,如果通过网络发送数据失败,可以将数据写入本地存储。当然,这时就必须定义如何处理该文件。

此外,上面提到的模式可以组合,比如像下面这个例子如下。

// 转换
try {
throw new IOException("Made up");
} catch (IOException e) {
throw new RuntimeException(e);
}
// 重试5次后放弃
boolean end = false;
int count = 0;
while (end == false) {
try {
// 发送信息
if (true) {
throw new MessagingException("Made up");
}
end = true;
} catch (MessagingException e) {
if (count >= 5) {
// 尝试5次放弃。
throw new RuntimeException("was not able to send message even after five tries", e);
}
++count;
try {
Thread.sleep(30000);
} catch (InterruptedException e1) {
Thread.currentThread().interrupt();
throw new RuntimeException(e1);
}
}
}
// 恢复:如果传输失败记录到文件
try {
// 发送信息
throw new MessagingException("Made up");
} catch (MessagingException e) {
try {
// 写文件
throw new IOException("Made up");
} catch (IOException e1) {
// 如果写文件失败,不再进行恢复
throw new RuntimeException(e1);
}
}

如果一切都失败了,那么上面这种方法至少可以确保你能意识到问题所在。 此外,它还提供了问题的真正原因,从而让你能快速定位问题。

祝编程快乐!

文章目录