Java异常框架设计

什么是异常?

异常(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这样的异常暴露给客户的,因为他们没有解决这个问题的责任!

相关文章:

http://blog.csdn.net/luqin1988/article/details/7970792

时间: 2024-10-11 05:01:06

Java异常框架设计的相关文章

JAVA基础教程之JAVA异常机制

今天我们主要来说一说JAVA异常机制方面的内容.自设JAVA学习群457036818,大家可以交流一下 一. 异常的概念和Java异常体系结构 异常是程序运行过程中出现的错误.本文主要传授的是一些滚与Java语言的异常处理.Java语言的异常处理框架,是Java语言健壮性的一个重要体现. Java把异常当作对象来处理,而且定义一个基类java.lang.Throwable作为所有异常的超类.在Java API中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception.J

【公开课:Java开源框架服务及CEP深入剖析】直播QQ群:228977971

一.课程简介 Java开源框架的服务体系是如何运行的? 什么是CEPCore?Java开源框架的服务有哪些关键要点? 如何根据用户的服务自动生成相关服务包装类? 来吧!一线开源框架资深设计师与你分享Java实战心得,手把手教你Java开源框架设计技巧! 二.主题 <Tiny服务及CEP深入剖析> 三.时间 2015-8-13(周四晚 20:00整) 四.课程地址 http://bbs.tinygroup.org/thread-1191-1-1.html 五.适合人群 A.对Tiny框架有兴趣的

Atitit.异常的设计原理与&#160;策略处理&#160;java&#160;最佳实践&#160;p93

Atitit.异常的设计原理与 策略处理 java 最佳实践 p93 1 异常方面的使用准则,答案是::2 1.1 普通项目优先使用异常取代返回值,如果开发类库方面的项目,最好异常机制与返回值都提供,由调用者决定使用哪种方式..2 1.2 优先把异常抛出到上层处理..异常本身就是为了方便把异常情况抛出到上层处理..2 1.3 对于 HYPERLINK \l _Toc6222 方法调用结果异常情况返回策略,最终会有四种策略状况,2 1.4 返回null  还是异常??2 2 异常的由来与设计3 2

Java集合框架中隐藏的设计套路

我们的世界不应该只有"胡萝卜" 进入正题之前容我先扯点别的. 最近突然想到了一个驴子和胡萝卜不得不说的故事.说是一个人坐在驴子背上,用一根长杆绑着一根胡萝卜,然后把胡萝卜悬到驴子的面前,驴子以为只要向前走一步就可以吃到胡萝卜,于是不停地向前走,可是它始终无法吃到这根萝卜. 一千个读者就有一千个哈姆雷特,当然不同的人对这个故事也会有不同的理解.比如我们为了生活拼命地工作,却永远达不到财务自由,我们是不是也像一只忙碌的"驴子"呢? 所以,我们的世界不应该只有"

处理异常、常用类、反射、类加载与垃圾回收、java集合框架

异常处理概述 检查异常:检查异常通常是用户错误或者不能被程序员所预见的问题.(cheched) 运行时异常:运行时异常是一个程序在运行过程中可能发生的.可以被程序员避免的异常类型.(Unchecked)RentimeExeption 错误:实际上,错误根本不是异常,但却是用户或程序员所无法控制的问题. 异常是程序在执行过程中所产生的问题.JVM发生了内存溢出等... 异常处理:method()方法有三种 1 捕获这个异常,不让他沿着调用栈继续向下抛出 2 捕获这个异常,并继续向下抛出 3 从而导

java异常设计

异常的分类结构图 异常机制是为了解决什么问题? 它也是线程结束的一种方式,从某中角度来讲,它与正常return没有什么区别,只不过是一种异常的方式结束.那为什么需要这种异常的机制呢?异常机制本身也是划分了严重程度,如:Error/Exception. 它以一种不侵入正常流程编码的形式,尽量不让程序崩溃(Error类型的异常), 同时给开发者友好的提示信息(方便问题的定位). 各种异常在什么场景下出现?能否处理? Error错误 这种异常通常都是程序级别的错误,直接会引起程序崩溃. 常见的异常有:

JAVA集合框架

收藏 查看我的收藏 146有用+1 56 编辑 Java,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台的总称.用Java实现的HotJava浏览器(支持Java applet)显示了Java的魅力:跨平台.动态的Web.Internet计算.从此,Java被广泛接受并推动了Web的迅速发展,常用的浏览器现在均支持Java applet.集合框架是为表示和操作集合而规定的一种统一的标准的体系结构.任何集合框架都包含三大块内容:对外的接口.接口的实

Java 日志框架终极教程

概述 对于现代的 Java 应用程序来说,只要被部署到真实的生产环境,其日志的重要性就是不言而喻的,很难想象没有任何日志记录功能的应用程序被运行于生产环境中.日志 API 所能提供的功能是多种多样的,包括记录程序运行时产生的错误信息.状态信息.调试信息和执行时间信息等.在生产环境中,日志是查找问题来源的重要依据,应用程序运行时的产生的各种重要信息,都应该通过日志 API 来进行记录. 很多Java开发人员习惯于使用 System.out.println.System.err.println 以及

java异常处理和设计

在程序设计中,进行异常处理是非常关键和重要的一部分.一个程序的异常处理框架的好坏直接影响到整个项目的代码质量以及后期维护成本和难度.试想一下,如果一个项目从头到尾没有考虑过异常处理,当程序出错从哪里寻找出错的根源?但是如果一个项目异常处理设计地过多,又会严重影响到代码质量以及程序的性能.因此,如何高效简洁地设计异常处理是一门艺术,本文下面先讲述Java异常机制最基础的知识,然后给出在进行Java异常处理设计时的几个建议. 若有不正之处,请多多谅解和指正,不胜感激. 请尊重作者劳动成果,转载请标明