Java开发框架之异常框架设计.docx
《Java开发框架之异常框架设计.docx》由会员分享,可在线阅读,更多相关《Java开发框架之异常框架设计.docx(8页珍藏版)》请在冰豆网上搜索。
Java开发框架之异常框架设计
概念
什么是异常?
异常(exception应该是异常事件(exceptionalevent的缩写。
异常定义:
异常是一个在程序执行期间发生的事件,它中断正在执行的程序的正常的指令流。
当在一个方法中发生错误的时候,这个方法创建一个对象,并且把它传递给运行时系统。
这个对象被叫做异常对象,它包含了有关错误的信息,这些信息包括错误的类型和在程序发生错误时的状态。
创建一个错误对象并把它传递给运行时系统被叫做抛出异常。
一个方法抛出异常后,运行时系统就会试着查找一些方法来处理它。
这些处理异常的可能的方法的集合是被整理在一起的方法列表,这些方法能够被发生错误的方法调用。
这个方法列表被叫做堆栈调用(call stack
运行时系统搜寻包含能够处理异常的代码块的方法所请求的堆栈。
这个代码块叫做异常处理器,搜寻首先从发生的方法开始,然后依次按着调用方法的倒序检索调用堆栈。
当找到一个相应的处理器时,运行时系统就把异常传递给这个处理器。
一个异常处理器要适当地考滤抛出的异常对象的类型和异常处理器所处理的异常的类型是否匹配。
异常被捕获以后,异常处理器关闭。
如果运行时系统搜寻了这个方法的所有的调用堆栈,而没有找到相应的异常处理器。
怎么设计异常框架
任何的异常都是Throwable类(为何不是接口?
?
并且在它之下包含两个字类Error/Exception,而Error仅在当在Java虚拟机中发生动态连接失败或其它的定位失败的时候,Java虚拟机抛出一个Error对象。
典型的简易程序不捕获或抛出Errors对象,你可能永远不会遇到需要实例化Error的应用,那就让我们关心一下Exception
Exception中比较重要的就是RuntimeException-运行时异常(当然这个名字是存在争议的,因为任何的异常都只会发生在运行时,为什么说这个类时很重要的呢?
因为它直接关系到你的异常框架的设计,仔细看RuntimeException
AmethodisnotrequiredtodeclareinitsthrowsclauseanysubclassesofRuntimeExceptionthatmightbethrownduringtheexecutionofthemethodbutnotcaught.
-可能在执行方法期间抛出但未被捕获的RuntimeException的任何子类都无需在throws子句中进行声明。
也就是说你的应用应该不去“关心”(说不关心是不服责任的,但只是你不应该试图实例化它的字类RuntimeException,就如同你不应该关心Error的产生与处理一样!
RuntimeException描述的是程序的错误引起来的,因该由程序负担这个责任!
(从责任这个角度看Error属于JVM需要负担的责任;RuntimeException是程序应该负担的责任;checkedexception是具体应用负担的责任
那就有人会问,那我该关心什么!
答案就是除了Error与RuntimeException,其他剩下的异常都是你需要关心的,而这些异常类统称为CheckedException,至于Error与RuntimeException则被统称为UncheckedException.
异常的概念就这些了,即使你在网络上搜索也就不过如此,是不是感觉到有点清晰又有点模糊?
那么怎么该如何在这样单薄而模糊的概念下设计J2EE的异常框架呢?
解决方案:
J2EE异常框架
我们拿一个模拟的例子来说明异常框架的设计过程,比如我们要对外提供doBusiness(这个业务方法
publicvoiddoBusiness(throwsxxxBusinessException
当客户端调用这样的方法的时候应该这样处理异常(包括处理RuntimeException,checkedexception
记住,无论如何我们都不希望或者确切的说是不应该将RuntimeException这样的异常暴露给客户的,因为他们没有解决这个问题的责任!
我们暂时将Struts中的某个Action看作时客户端,其中doExecute(....要调用doBusiness(这个方法
publicvoiddoAction(......
{
try
{
xxx.doBusiness(;
}
catch(Exceptione
{
if(einstanceofRuntimeException
{
//catchruntimeexception
//你可以在这里将捕获到的RuntimeException
//将异常通知给某个负责此程序的程序员,让他知道他
//自己犯了多么低级的错误!
}else
{
//checkedexceptionsuchasxxxBusinessException
//将这样的异常暴露给客户显示
}
}
}
我们可以这样设计xxxBusinessException
publicclassxxxBusinessExceptionextendsApplicationException
{
publicxxxBusinessException(Strings{
super(s;
};
importjava.io.PrintStream;
importjava.io.PrintWriter;
publicclassApplicationExceptionextendsException{
/**AwrappedThrowable*/
protectedThrowablecause;
publicApplicationException({
super("Erroroccurredinapplication.";
}
publicApplicationException(Stringmessage{
super(message;
}
publicApplicationException(Stringmessage,Throwablecause{super(message;
this.cause=cause;
}
//CreatedtomatchtheJDK1.4Throwablemethod.
publicThrowableinitCause(Throwablecause{
this.cause=cause;
returncause;
}
publicStringgetMessage({
//Getthisexception'smessage.
Stringmsg=super.getMessage(;
Throwableparent=this;
Throwablechild;
//Lookfornestedexceptions.
while((child=getNestedException(parent!
=null{
//Getthechild'smessage.
Stringmsg2=child.getMessage(;
//Ifwefoundamessageforthechildexception,//weappendit.
if(msg2!
=null{
if(msg!
=null{
msg+=":
"+msg2;
}else{
msg=msg2;
}
}
//AnynestedApplicationExceptionwillappenditsown//children,soweneedtobreakoutofhere.
if(childinstanceofApplicationException{
break;
}
parent=child;
}
//Returnthecompletedmessage.
returnmsg;
}
publicvoidprintStackTrace({
//Printthestacktraceforthisexception.
super.printStackTrace(;
Throwableparent=this;
Throwablechild;
//Printthestacktraceforeachnestedexception.
while((child=getNestedException(parent!
=null{
if(child!
=null{
System.err.print("Causedby:
";
child.printStackTrace(;
if(childinstanceofApplicationException{
break;
}
parent=child;
}
}
}
publicvoidprintStackTrace(PrintStreams{
//Printthestacktraceforthisexception.
super.printStackTrace(s;
Throwableparent=this;
Throwablechild;
//Printthestacktraceforeachnestedexception.
while((child=getNestedException(parent!
=null{if(child!
=null{
s.print("Causedby:
";
child.printStackTrace(s;
if(childinstanceofApplicationException{break;
}
parent=child;
}
}
}
publicvoidprintStackTrace(PrintWriterw{
//Printthestacktraceforthisexception.
super.printStackTrace(w;
Throwableparent=this;
Throwablechild;
//Printthestacktraceforeachnestedexception.
while((child=getNestedException(parent!
=null{if(child!
=null{
w.print("Causedby:
";
child.printStackTrace(w;
if(childinstanceofApplicationException{break;
}
parent=child;
}
}
}
publicThrowablegetCause({
returncause;
}
}
而"聪明"的读者肯定要问我那doBusiness(这个业务方法该如何包装异常呢?
publicvoiddoBusiness(throwxxxBusinessException
{
try
{
execute1(;//ifitthrowexception1
exexute2(;//ifitthrowexception2
......