什么是异常?

异常(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

转载于:https://www.cnblogs.com/yanghj010/p/5075853.html

Java异常框架设计相关推荐

  1. 【学习笔记】【Design idea】一、Java异常的设计思想、性能相关、笔记

    1.前言: 异常.本该是多么优雅的东西,然而,得全靠自己在零散的信息中汇集. 学习笔记保持更新. 2.教材(参考资料) 其他 ①受检异常与非受检异常:https://www.cnblogs.com/j ...

  2. java 简单 框架_java简单框架设计

    设计框架包可以作为一个工具给大家用,需要有完全不同设计思路给出来,不同于我们去做一个web服务.网站. 或者一个业务微服务,需要从原来使用视角转换成一个构建者视角. 框架或者工具,更多是框架来管理或者 ...

  3. Java异常体系结构

    一. 异常的概念和Java异常体系结构 异常是程序运行过程中出现的错误.本文主要讲授的是Java语言的异常处理.Java语言的异常处理框架,      是Java语言健壮性的一个重要体现. Java把 ...

  4. 异常的概念和Java异常体系结构

    一. 异常的概念和Java异常体系结构 异常是程序运行过程中出现的错误.本文主要讲授的是Java语言的异常处理.Java语言的异常处理框架,     是Java语言健壮性的一个重要体现. Java把异 ...

  5. Java异常(一) Java异常简介及其架构

    概要 本章对Java中的异常进行介绍.内容包括: Java异常简介 Java异常框架 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3544168.htm ...

  6. java 抛出异常_我的Java Web之路51 - Java异常基础

    本系列文章旨在记录和总结自己在Java Web开发之路上的知识点.经验.问题和思考,希望能帮助更多(Java)码农和想成为(Java)码农的人. 目录 介绍 异常的本质 Java异常的设计 Java异 ...

  7. Java异常的正确使用姿势

    2019独角兽企业重金招聘Python工程师标准>>> 最近在项目代码中,遇见异常滥用的情形,会带来什么样的后果呢? 1. 代码可读性变差,业务逻辑难以理解 异常流与业务状态流混在一 ...

  8. JavaWeb框架设计之菜单设计

    近来工作,要求自己搭建框架.从中遇到了这样一个诉求---动态菜单. 这个诉求在Java Web框架设计中属于最普遍的需求.那么我们来探讨下. 一般的Java Web框架的菜单层级都是为二级,那么在数据 ...

  9. java build path entries 为空_同事的代码简直没法看,我来教你如何更优雅的设计Java异常...

    点击上方蓝色字体,选择"设为星标" 回复"666"获取面试宝典 异常处理是程序开发中必不可少操作之一,但如何正确优雅的对异常进行处理确是一门学问,笔者根据自己的 ...

  10. 教你如何更优雅的设计Java异常

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源:lrwinx https://lrwinx.github.i ...

最新文章

  1. Java线程池详解学习:ThreadPoolExecutor
  2. 95页重磅报告:全面预测未来5年趋势
  3. hadoop学习--单表关联
  4. 【NLP】文本相似度的BERT度量方法
  5. oracle 排序的分析函数,Oracle分析函数用法详解
  6. 迭代器模式源码解析(jdk+mybatis)
  7. 按钮点击计数器存入mysql_按钮点击数统计计数器(PHP+MYSQL+JS)
  8. 解决Hibernate4执行update操作,不更新数据的问题
  9. python - Numpy - matplotlib
  10. Android pm命令(持续更新中...)
  11. 双系统ubuntu无法进入_win10下安装ubuntu双系统
  12. VS 2015专业版密钥
  13. bp神经网络的算法步骤,BP神经网络算法流程图
  14. 关于USGS 共享光谱库读取问题
  15. 靠微信小程序两周获客20万,同城小程序开始爆发
  16. Redis 客户端哪家强? Lettuce手下见真香!
  17. android实现刷卡功能,Android 实现银联刷卡机消费后手动签名的功能(示例代码)
  18. Android打开自启动设置页面
  19. 用ios企业证书发布ipa到服务器上扫码下载
  20. icesword 是如何列出隐藏进程?

热门文章

  1. atitit.故障排除--- 当前命令发生了严重错误。应放弃任何可能产生的结果sql server 2008
  2. paip.信用卡账单处理系统功能vO22
  3. paip.python错误解决5
  4. 盘点国内外私募基金业绩报酬计提方式
  5. Julia : win下cmd和repl中执行.jl程序
  6. (转)对冲基金不信中国经济数据,转用卫星监控6000块工业用地
  7. 11位大牛与您共建数智升级路径
  8. 那些年,我们踩过的 Java 坑 | 凌云时刻
  9. 2022美国大学生数学建模竞赛D题思路
  10. java 多线程 保存txt_一个txt文件,里面存在几万条数据,现用多线程实现数据导入,提高效率,java代码如何实现...