java异常处理策略_【译】Java异常处理策略

翻译:疯狂的技术宅

原文标题:Exception handling strategy

原文链接:http://programmergate.com/exc...

本文首发微信公众号:充实的脑洞

在本文中,我们介绍了在OOP应用中处理异常的常见策略,这些策略符合最佳的异常处理技术,可以在任何应用中使用。

1. 概述

下图提供了策略概述,它展示了从检测阶段到处理阶段的异常处理流程。该图需要从下往上进行阅读:

Error detection: 在策略的底部是错误检测,这是发生异常的地方,它要么由程序进行检测,要么由一些外部调用引发。

Local exception handling: 在第二级是本地异常处理,检测错误的类尝试在本地处理异常,例如:将请求发送到备份服务器,或等待X秒后再次尝试等...如果异常无法恢复,则将其传播到较高级别。

Propagate exception to higher levels: 当本地错误处理不起作用时,该类收集诊断信息,再现和报告错误所需的所有信息,然后将该异常传到栈中。 如果检测到的异常不是低级别依赖(取决于低级别实现),那么它将被抛出,否则将被转换为自定义异常,以实现组件之间的解耦。

Keep propagating if nothing to do with the exception: 较高级别的类将会继续将异常传到栈中, 只要它们与异常无关。同时关闭在传递路径的所有资源(例如文件、网络连接、释放分配的缓冲区等),并添加相关的上下文信息, 这将有助于确定错误的原因和严重性。

Handle exception:在这个阶段,异常会到达一个负责处理它的类,异常所携带的所有错误信息都记录在此,并且根据异常的严重性,该类可以处理异常或者结束程序。

2. 自定义异常模板

实现异常处理策略时要做的第一件事就是,为程序的每个组件创建自定义异常,自定义异常如下所示:

public class ComponentException extends Exception {

private static final long serialVersionUID = 1L;

private int errorCode;

private String errorDescription;

private boolean isSevere;

public ComponentException() {

super();

}

public ComponentException(Exception ex) {

super(ex);

}

public int getErrorCode() {

return errorCode;

}

public void setErrorCode(int errorCode) {

this.errorCode = errorCode;

}

public String getErrorDescription() {

return errorDescription;

}

public void setErrorDescription(String errorDescription) {

this.errorDescription = errorDescription;

}

public boolean isSevere() {

return isSevere;

}

public void setSevere(boolean isSevere) {

this.isSevere = isSevere;

}

}

以下描述了ComponentException类的属性:

errorCode:识别此错误的唯一代码,errorCode告诉我们那里出错了,程序的所有错误代码应在静态类中进行预定义。该属性指示异常捕获代码应该怎样处理这个错误。

errorDescription: 对错误的描述,描述了用户、程序操作人员和可能的程序开发人员所需的一切必要的细节,可以使他们了解到底发生了什么错误。

isSevere: 指示该错误是否严重,此属性会在该异常根据错误的上下文遍历堆栈时进行更新,严重性会指示异常捕获代码是应该停止程序还是该继续处理。

3.引发异常

在检测到错误并无法从中恢复时,异常将向上传播到调用堆栈,直到到达处理它的某个 try-catch块。该异常可以按原样传递,也可转换为自定义异常。

3.1 抛出异常

如果异常不依赖于定期更改的低级实现或动态实现,那么你只需关闭打开的资源,并把异常积蓄传到调用栈而不去捕获它。下面是一个例子:

public void doSomething() throws SomeException {

try{

doSomethingThatCanThrowException();

} finally {

//close the opened resources

}

}

3.2 抛出自定义异常

当捕获的异常取决于低级别或动态实现时,它会被转换为一个特定的异常,然后重新启动调用堆栈。 下面是一个例子:

public Student readStudent(String id) throws SomeException {

try

{

// Some code which reads a student from oracle database

}

catch(SQLException ex)

{

DataAccessException dataAccessException = new DataAccessException(ex);

dataAccessException.setErrorCode(101); // we assume this code denotes student not found

dataAccessException.setErrorMessage("An error occurred while reading " +

"student with id: " + id + " from database");

dataAccessException.setSeverity(false);

throw dataAccessException;

}

}

只要它还没有到达能够处理它的类,异常就会继续传播。

P.S:强烈建议在异常传播到堆栈时更新异常的严重性,无论是异常被继续抛出,还是转换为自定义异常。

4. 捕获异常

在程序中,你需要捕获并响应来抛出异常,通常你需要在调用层次的顶部执行此操作。

捕获异常时首先要做的是记录它,通常我更喜欢使用printStackTrace(),之后的处理过程取决于异常的严重性:

如果严重,则通知开发人员和程序操作人员,并且结束程序。

如果不严重,则根据错误代码完成处理。通常有两种可能性,可以静默地从异常中恢复,或者通知最终用户并停止当前进程。

下面是一个例子:

try{

startTheWholeThing();

} catch(MyAppException e) {

e.printStackTrace();

if(e.isSevere())

{

notifyNonUsers(e);

// Halt the system gracefully

}

else

{

if(e.getErrorCode() == 100)

{

// do some silent recovery logic

}

else

{

notifyUsers(e);

}

}

}

以上是我在程序中处理异常时所遵循的策略,希望你能喜欢。

关注微信公众号:充实的脑洞, 一个技术宅的保留地

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值