概念
什么是异常?
异常(exception)应该是异常事件(exceptional event)的缩写。
异常定义:异常是一个在程序执行期间发生的事件,它中断正在执行的程序的正常的指令流。
当在一个方法中发生错误的时候,这个方法创建一个对象,并且把它传递给运行时系统。这个对象被叫做异常对象,它包含了有关错误的信息,这些信息包括错误的类型和在程序发生错误时的状态。创建一个错误对象并把它传递给运行时系统被叫做抛出异常。
一个方法抛出异常后,运行时系统就会试着查找一些方法来处理它。这些处理异常的可能的方法的集合是被整理在一起的方法列表,这些方法能够被发生错误的方法调用。这个方法列表被叫做堆栈调用(call stack)
运行时系统搜寻包含能够处理异常的代码块的方法所请求的堆栈。这个代码块叫做异常处理器,搜寻首先从发生的方法开始,然后依次按着调用方法的倒序检索调用堆栈。当找到一个相应的处理器时,运行时系统就把异常传递给这个处理器。一个异常处理器要适当地考滤抛出的异常对象的类型和异常处理器所处理的异常的类型是否匹配。异常被捕获以后,异常处理器关闭。如果运行时系统搜寻了这个方法的所有的调用堆栈,而没有找到相应的异常处理器。
怎么设计异常框架
任何的异常都是Throwable类(为何不是接口??),并且在它之下包含两个字类Error / Exception,而Error仅在当在Java虚拟机中发生动态连接失败或其它的定位失败的时候,Java虚拟机抛出一个Error对象。典型的简易程序不捕获或抛出Errors对象,你可能永远不会遇到需要实例化Error的应用,那就让我们关心一下Exception
Exception中比较重要的就是RuntimeException-运行时异常(当然这个名字是存在争议的,因为任何的异常都只会发生在运行时),为什么说这个类时很重要的呢?因为它直接关系到你的异常框架的设计,仔细看RuntimeException
A method is not required to declare in its throws clause any subclasses of RuntimeException that might be thrown during the execution of the method but not caught.
-可能在执行方法期间抛出但未被捕获的 RuntimeException 的任何子类都无需在 throws 子句中进行声明。
也就是说你的应用应该不去“关心”(说不关心是不服责任的,但只是你不应该试图实例化它的字类)RuntimeException,就如同你不应该关心 Error的产生与处理一样!RuntimeException描述的是程序的错误引起来的,因该由程序负担这个责任!(<B>从责任这个角度看Error属于JVM需要负担的责任;RuntimeException是程序应该负担的责任;checked exception 是具体应用负担的责任</B>)
那就有人会问,那我该关心什么!答案就是除了Error与 RuntimeException,其他剩下的异常都是你需要关心的,而这些异常类统称为Checked Exception,至于Error与RuntimeException则被统称为Unchecked Exception.
异常的概念就这些了,即使你在网络上搜索也就不过如此,是不是感觉到有点清晰又有点模糊?那么怎么该如何在这样单薄而模糊的概念下设计J2EE的异常框架呢?
解决方案:J2EE异常框架
我们拿一个模拟的例子来说明异常框架的设计过程,比如我们要对外提供doBusiness()这个业务方法
public void doBusiness() throws xxxBusinessException
当客户端调用这样的方法的时候应该这样处理异常(包括处理RuntimeException , checked exception)
<B>记住,无论如何我们都不希望或者确切的说是不应该将RuntimeException这样的异常暴露给客户的,因为他们没有解决这个问题的责任!</B>
我们暂时将Struts中的某个Action看作时客户端,其中doExecute(....)要调用doBusiness()这个方法
public void doAction(......)
{
try
{
xxx.doBusiness();
}
catch(Exception e)
{
if(e instanceof RuntimeException)
{
// catch runtime exception
// 你可以在这里将捕获到的RuntimeException
// 将异常通知给某个负责此程序的程序员,让他知道他
// 自己犯了多么低级的错误!
}else
{
//checked exception such as xxxBusinessException
//将这样的异常暴露给客户显示
}
}
}
我们可以这样设计xxxBusinessException
public class xxxBusinessException extends ApplicationException
{
public xxxBusinessException(String s){
super(s);
};
import java.io.PrintStream;
import java.io.PrintWriter;
public class ApplicationException extends Exception {
/** A wrapped Throwable */
protected Throwable cause;
public ApplicationException() {
super("Error occurred in application.");
}
public ApplicationException(String message) {
super(message);
}
public ApplicationException(String message, Throwable cause) {
super(message);
this.cause = cause;
}
// Created to match the JDK 1.4 Throwable method.
public Throwable initCause(Throwable cause) {
this.cause = cause;
return cause;
}
public String getMessage() {
// Get this exception's message.
String msg = super.getMessage();
Throwable parent = this;
Throwable child;
// Look for nested exceptions.
while((child = getNestedException(parent)) != null) {
// Get the child's message.
String msg2 = child.getMessage();
// If we found a message for the child exception,
// we append it.
if (msg2 != null) {
if (msg != null) {
msg += ": " + msg2;
} else {
msg = msg2;
}
}
// Any nested ApplicationException will append its own
// children, so we need to break out of here.
if (child instanceof ApplicationException) {
break;
}
parent = child;
}
// Return the completed message.
return msg;
}
public void printStackTrace() {
// Print the stack trace for this exception.
super.printStackTrace();
Throwable parent = this;
Throwable child;
// Print the stack trace for each nested exception.
while((child = getNestedException(parent)) != null) {
if (child != null) {
System.err.print("Caused by: ");
child.printStackTrace();
if (child instanceof ApplicationException) {
break;
}
parent = child;
}
}
}
public void printStackTrace(PrintStream s) {
// Print the stack trace for this exception.
super.printStackTrace(s);
Throwable parent = this;
Throwable child;
// Print the stack trace for each nested exception.
while((child = getNestedException(parent)) != null) {
if (child != null) {
s.print("Caused by: ");
child.printStackTrace(s);
if (child instanceof ApplicationException) {
break;
}
parent = child;
}
}
}
public void printStackTrace(PrintWriter w) {
// Print the stack trace for this exception.
super.printStackTrace(w);
Throwable parent = this;
Throwable child;
// Print the stack trace for each nested exception.
while((child = getNestedException(parent)) != null) {
if (child != null) {
w.print("Caused by: ");
child.printStackTrace(w);
if (child instanceof ApplicationException) {
break;
}
parent = child;
}
}
}
public Throwable getCause() {
return cause;
}
}
而"聪明"的读者肯定要问我那doBusiness()这个业务方法该如何包装异常呢?
public void doBusiness() throw xxxBusinessException
{
try
{
execute1(); // if it throw exception1
exexute2(); // if it throw exception 2
.... .....
}
catch (exception1 e1)
{
throw new xxxBusinessException(e1);
}
catch(exception2 e2)
{
throw new xxxBusinessException(e2);
}
........
}
也可以这样
public void doBusiness() throw xxxBusinessException
{
try
{
execute1(); // if it throw exception1
exexute2(); // if it throw exception 2
.... .....
}
catch (Exception e)
{
// 注意很多应用在这里根本不判断异常的类型而一股脑的采用
// throw new xxxBusinessException(e);
// 而这样带来的问题就是xxxBusinessException"吞掉了"RuntimeException
// 从而将checked excption 与unchecked exception混在了一起!
// 其实xxxBusinessException属于checked excpetion ,它根本不应该也不能够理睬RuntimeException
if(! e instanceof RuntimeException) throw new xxxBusinessException(e);
}
}
总结
1。JAVA的异常分为两类: checked exception & unchecked excpetion
2。应用开发中产生的异常都应该集成自Exception 但都属于checked excpetion类型
3。应用中的每一层在包装并传递异常的时候要过滤掉RuntimeException!
4。从责任这个角度看Error属于JVM需要负担的责任;RuntimeException是程序应该负担的责任;checked exception 是具体应用负担的责任
5。无论如何我们都不希望或者确切的说是不应该将RuntimeException这样的异常暴露给客户的,因为他们没有解决这个问题的责任!
分享到:
相关推荐
智能用电异常系统设计 随着社会的进步和经济的发展,电力供应已经能够满足经济发展的需要,但如何提高供电服务、保护用电,更好地服务社会和经济发展,是电网企业需要面临的趋势。因此,针对用电异常,研发并采用...
离线智能用电异常系统设计是现代电力管理领域中的一个重要议题,它主要关注如何通过数据分析来检测和预测家庭、商业或工业环境中的用电异常情况。这种系统通常基于大数据技术和机器学习算法,旨在提高能源效率,保障...
基于数据挖掘技术的用电异常分析系统设计.pdf
通过以上知识点的详细论述,我们可以了解到云计算平台异常行为检测系统设计的重要性,以及实现该系统所采取的技术手段和管理策略。此外,也认识到实验验证的重要性,实验结果不仅证明了技术方案的有效性,也为系统的...
这篇博文“Java异常框架设计”可能探讨了如何有效地利用Java的异常处理机制来构建可靠的系统。在这个讨论中,我们将深入理解Java异常的基本概念、异常分类、以及如何通过良好的框架设计提升代码的可读性和可维护性。...
基于Hook 的程序异常行为检测系统设计与实现.pdf
为解决KJ405T井下作业人员管理系统的异常情况的声光报警及发起报警流程的问题,设计了基于大量采集的定位数据而提起的异常报警流程;结合Visual C++编程技术,采用Timer定时器、ADO.NET2.0数据库访问技术,开发实现了KJ...
在IT行业中,系统设计是软件开发过程中的关键环节,它涉及到架构设计、概要设计、详细设计和数据库设计等多个步骤。这些步骤都是确保项目成功、高效且可维护的关键。以下是对这些知识点的详细阐述: 1. **架构设计*...
### 基于ARM的嵌入式系统程序开发要点(四)——异常处理机制的设计 在基于ARM架构的嵌入式系统开发过程中,异常处理机制的设计是确保系统稳定性和可靠性的关键因素之一。本文将围绕异常处理机制进行深入探讨,包括但...
基于VR技术的电力系统异常情况巡检系统设计 电力系统是指由发电场站、输电线路、配电场站和用电侧共同组成的综合性的电能生产与消费系统。其功能是将自然能源转化为电能,再通过变电、输送和配电过程供应给电力用户...
《电力系统低压台区用户表码异常监控系统设计》一文探讨了在电力系统中如何有效地监控低压台区用户的表码异常情况,以提升电力系统的稳定性和效率。该系统设计主要涉及两个核心部分:硬件运行环境的构建和软件运行...
"计算机网络病毒检测系统设计与实现研究" 本文主要研究了计算机网络病毒检测系统的设计与实现,旨在解决计算机网络安全问题。随着计算机网络的发展,网络安全问题变得越来越重要,病毒检测系统作为一种新型技术,...
3. 容错能力:设计系统时应考虑容错机制,确保单个组件故障不会导致整个系统的崩溃。 4. 数据保护:确保在异常情况下,关键数据的安全性和完整性不受损害。 5. 回滚与恢复:有计划的回滚策略和备份恢复机制,能在...
这说明基于深度强化学习的财务异常数据检测系统具备高效、稳定、准确的特点,完全能够满足医疗财务系统对于异常数据检测的需求,从而保障医院财务的正常运作。 此外,该系统的构建和应用将有助于规范医院财务收入,...
基于互联网的电子信息数据异常监测系统设计旨在克服传统监测系统在功能和性能上的局限性,利用互联网+的技术优势,实现更高效、准确的异常检测。系统设计涵盖了硬件系统、数据库系统和软件系统三个关键层面。 硬件...
在我们的设计中,CPU被扩展以处理异常和中断,这是操作系统和实时系统中的关键功能。 异常是CPU在执行过程中遇到的错误或不可预见情况,如算术溢出。算术溢出发生在运算结果超出可表示的数值范围时。CPU需要能够...
这份模板旨在提供一个全面的框架,帮助开发者理解系统设计的全貌,同时确保设计的每个部分都与项目的目标和约束相一致。通过遵循这样的设计过程,可以提高软件开发的质量和效率,降低后期维护的成本。在实际工作中,...
在软件开发过程中,详细设计是至关重要的一个环节。它是在概要设计的基础上,对软件系统的各个组成部分进行具体的、深入的设计,...通过学习和应用这些知识,开发者可以更有效地进行系统设计,提高软件质量和开发效率。
GPS位置历史挖掘和移动轨迹异常检测系统的设计与实现 基于GPS位置历史数据挖掘和移动轨迹异常检测系统的设计与实现是近年来位置感知技术发展的重要研究方向之一。该系统的设计和实现可以帮助发现候鸟的公共移动模式...
- 这部分通常简述系统设计的整体思路和理念,可能包括设计原则、架构选择等。 3. **系统详细需求分析**: - 这是基于概要设计阶段的需求,对每个功能模块进行深入的细化,包括功能需求、性能需求、接口需求等。 ...