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
Java异常框架设计的更多相关文章
- Java 异常框架
一张图看懂Java 异常框架之间的关系. 说明: 受检异常:编译的时候报错. 费受检异常:运行时报错,需要知道几个常见的异常 NullPointerException(空指针异常) ArrayInde ...
- 【学习笔记】【Design idea】一、Java异常的设计思想、性能相关、笔记
1.前言: 异常.本该是多么优雅的东西,然而,得全靠自己在零散的信息中汇集. 学习笔记保持更新. 2.教材(参考资料) 其他 ①受检异常与非受检异常:https://www.cnblogs.com/j ...
- Getty – Java NIO 框架设计与实现
前言 Getty是我为了学习 Java NIO 所写的一个 NIO 框架,实现过程中参考了 Netty 的设计,同时使用 Groovy 来实现.虽然只是玩具,但是麻雀虽小,五脏俱全,在实现过程中,不仅 ...
- Selenium2(java)框架设计 九
设计框架原则: 数据分离,业务层和逻辑层不要混杂在一起. 设计图: 框架结构初始化: com.wymall.test:这是存放这个框架源代码的根目录 base:里面有个基类(BaseParpaare. ...
- java简单框架设计
设计框架包可以作为一个工具给大家用,需要有完全不同设计思路给出来,不同于我们去做一个web服务.网站. 或者一个业务微服务,需要从原来使用视角转换成一个构建者视角. 框架或者工具,更多是框架来管理或者 ...
- Java+Selenium3框架设计篇5-如何实现邮件发送测试报告
https://blog.csdn.net/u011541946/article/details/77278837 本篇继续回答网友的问题,这个主题是如何通过邮件发送测试报告.通过邮件发送测试报告,这 ...
- 一篇很好的java异常框架讲解
https://www.cnblogs.com/itcui/p/6400499.html 其实原作者是csdn的一名博主,实在受不了csdn的广告,所以就摘录这篇
- Java异常(一)Java异常简介及其框架
Java异常(一)Java异常简介及其框架 概要 本章对Java中的异常进行介绍.内容包括:Java异常简介Java异常框架 Java异常简介 Java异常是Java提供的一种识别及响应错误的一致性机 ...
- 异常的概念和Java异常体系结构
一. 异常的概念和Java异常体系结构 异常是程序运行过程中出现的错误.本文主要讲授的是Java语言的异常处理.Java语言的异常处理框架, 是Java语言健壮性的一个重要体现. Ja ...
随机推荐
- 在表单里面检查用户名是否存javascript
function CheckUser(fn) { $.get("/Pages/Handler/CheckExistHander.ashx", { "txt_UserNo& ...
- JVM基础(1)——内存模型
转载:http://blog.csdn.net/weitry/article/details/53264262 系列文章规划: JVM基础(1)——内存模型 JVM基础(2)——内存管理 JVM基础( ...
- 聊聊iOS中网络编程长连接的那些事
1.长连接在iOS开发中的应用 常见的短连接应用场景:一般的App的网络请求都是基于Http1.0进行的,使用的是NSURLConnection.NSURLSession或者是AFNetworking ...
- 算法笔记_074:子集和问题(Java)
目录 1 问题描述 2 解决方案 2.1 全排列思想求解 2.2 状态空间树思想求解 1 问题描述 求n个正整数构成的一个给定集合A = {a1,a2,a3,...,an}的子集,子集的和要等于一 ...
- (转)职责链设计模式(Chain of Responsibility)
Chain of Responsibility定义Chain of Responsibility(CoR) 是用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合,唯 ...
- 基于Qt的A*算法可视化分析
代码地址如下:http://www.demodashi.com/demo/13677.html 需求 之前做过一个无人车需要自主寻找最佳路径,所以研究了相关的寻路算法,最终选择A算法,因为其简单易懂, ...
- oracle 查询 函数练习
/*--以下代码是对emp表进行显示宽度设置col empno for 9999;col ename for a10;col job for a10;col mgr for 9999; col hir ...
- JBOSS 中oracle-ds.xml的配置模板
http://blog.csdn.net/bo_hai/article/details/6076979 JBOSS 中oracle-ds.xml的配置模板. 代码模版: <?xml vers ...
- C# 视频监控系列:学习地址汇总
原文地址:http://www.cnblogs.com/over140/archive/2009/04/07/1429308.html 前言 对于视频监控系统大家应该是不陌生的,实施的路况信息.地铁. ...
- c语言中有bool型变量吗?
C语言里面是没有bool(布尔)类型的,C++里面才有,这就是说,在C++里面使用bool类型是没有问题的. bool类型有只有两个值:true =1 .false=0. 但是,C99标准里面,又定义 ...