摘要:指示该错误是否严重,此属性会在该异常根据错误的上下文遍历堆栈时进行更新,严重性会指示异常捕获代码是应该停止程序还是该继续处理。引发异常在检测到错误并无法从中恢复时,异常将向上传播到调用堆栈,直到到达处理它的某个块。
翻译:疯狂的技术宅
原文标题: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); } } }
以上是我在程序中处理异常时所遵循的策略,希望你能喜欢。
关注微信公众号:充实的脑洞, 一个技术宅的保留地 | |
---|---|
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/67719.html
摘要:近日,在上列举了开发中常见的个错误,与君共免。在多线程中并发修改集合内容是非常常见的,因此需要使用并发编程中常用的方法进行处理,例如同步锁对于并发修改采用特殊的集合等等。在单线程和多线程情况下解决这个问题有微小的差别。 在编程时,开发者经常会遭遇各式各样莫名错误。近日,Sushil Das 在 Geek On Java上列举了 Java 开发中常见的 5 个错误,与君共「免」。 原文...
摘要:生产者消费者问题是一个典型的多进程同步问题。生产者线程开始产生新的元素并将它们存储在缓冲区。否则,生产者线程将会在缓冲区创建一个新元素然后通知消费者。我们建立一个线程池,它将收到两个任务,生产者和消费者的任务。 原文链接:https://dzone.com/articles/th... 作者:Ioan Tinca 译者:liumapp 想要了解更多关于Java生产者消费者问题的演变吗?...
摘要:能否声明一个内容为空的接口可以。能否将接口声明为不允许,这样做会导致编译错误。当异常没有被捕获时,会发生什么当前线程所在的线程组会执行一个叫的方法,最后程序会异常退出。非静态内部类可以使用哪些修饰符非静态内部类可以使用或修饰符。 原文地址 http://www.instanceofjava.com/2014/12/core-java-interview-questions.html 1...
摘要:我们应该考虑使用字符串常量调用方法来代替使用对象调用该方法。然而如果我们通过字符串常量来调用方法,执行流程会正常进行检查方法的参数在执行方法的方法体之前,务必对方法的参数进行值检查。 原文地址作者 Sotirios-Efstathios (Stathis) Maneas译者 smallcloverThanks for your watching! java.lang.NullPoine...
摘要:每个消费者会得到平均数量的。为了确保不会丢失,采用确认机制。如果中断退出了关闭了,关闭了,或是连接丢失了而没有发送,会认为该消息没有完整的执行,会将该消息重新入队。该消息会被发送给其他的。当消费者中断退出,会重新分派。 Work模式 原文地址showImg(https://segmentfault.com/img/bVbqlXr?w=694&h=252); 在第一章中,我们写了通过一个...
阅读 581·2021-11-22 14:45
阅读 3070·2021-10-15 09:41
阅读 1554·2021-10-11 10:58
阅读 2796·2021-09-04 16:45
阅读 2604·2021-09-03 10:45
阅读 3238·2019-08-30 15:53
阅读 1221·2019-08-29 12:28
阅读 2132·2019-08-29 12:14