Java大佬给出的三种处理异常的建议

Java大佬给出的三种处理异常的建议

缘起:偶然看到了老外写的博客,读完觉得不错,分享一下。PS:原著地址

Oh no, don’t do this to me…

中文翻译:

哦,请不要这样写……

// 第一种:写一句注释跳过异常
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 - 处理异常 (;
}

… and still, I am finding those catch blocks inside various projects. This is a great way to suppress the problem — for a short period of time. A few weeks or months later, this will become a nightmare for developers. Walking through the old log files and trying to figure out what went wrong is definitely not that most people want to do. Therefore, let’s avoid that.

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

The first rule is that catch blocks are here to handle exceptional situations. Logging exceptions and moving on is not considered as handling. The only case when it makes sense to suppress exception is during the closing of the resource after a prior exception (this case isn’t covered within this article; if you are interested, then here is an old yet still very good blog post written by McDowell).

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

There are three basic patterns of how to handle exceptions: translate, retry, and recover.

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

Translate is often used when you have to deal with a checked exception, your method can’t bubble it up, and recovery is not possible. In such cases, it is appropriate to translate it into a runtime exception and throw up. Then, the runtime exception is typically handled in the framework level. Retry is useful when dealing with unreliable services. It makes sense only if retrying makes sense fundamentally. The good example is retrying to overcome network interruptions. Recover is good when the strategy for doing that is defined. For example, you can write data to the local storage if sending over network fails. Of course, then it’s necessary to define what to do with that file.

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

In addition, the mentioned patterns might be combined. Examples are as follows.

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

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

If everything fails, then this way will at least guarantee that you will be aware of the problem. In addition, it will provide you always the true cause of the issue; therefore, you will be able to quickly identify where the problem is!

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

Happy handling!

祝编程快乐!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值