深入探索 高效的Java异常处理框架
转载自:http://www.sunwei.org/archives/196
摘要:本文从Java异常最基本的概念、语法开始讲述了Java异常处理的基本知识,分析了Java异常体系结构,对比Spring的异常处理框架,阐述了异常处理的基本原则。并且作者提出了自己处理一个大型应用系统异常的思想,并通过设计一个异常处理的框架来论述此思想。

二、 异常的捕获和处理
Java异常的捕获和处理是一个不容易把握的事情,如果处理不当,不但会让程序代码的可读性大大降低,而且导致系统性能低下,甚至引发一些难以发现的错误。
Java异常处理涉及到五个关键字,分别是:try、catch、finally、throw、throws。下面将骤一介绍,通过认识这五个关键字,掌握基本异常处理知识。
1、 异常处理的基本语法
在java中,异常处理的完整语法是:

- try{
- //(尝试运行的)程序代码
- }catch(异常类型 异常的变量名){
- //异常处理代码
- }finally{
- //
- }
以上语法有三个代码块:
try语句块,表示要尝试运行代码,try语句块中代码受异常监控,其中代码发生异常时,会抛出异常对象。
catch语句块会捕获try代码块中发生的异常并在其代码块中做异常处理,catch语句带一个Throwable类型的参数,表示可捕获异常类型。当try中出现异常时,catch会捕获到发生的异常,并和自己的异常类型匹配,若匹配,则执行catch块中代码,并将catch块参数指向所抛的异常对象。catch语句可以有多个,用来匹配多个中的一个异常,一旦匹配上后,就不再尝试匹配别的catch块了。通过异常对象可以获取异常发生时完整的JVM堆栈信息,以及异常信息和异常发生的原因等。
finally语句块是紧跟catch语句后的语句块,这个语句块总是会在方法返回前执行,而不管是否try语句块是否发生异常。并且这个语句块总是在方法返回前执行。目的是给程序一个补救的机会。这样做也体现了Java语言的健壮性。
2、 try、catch、finally三个语句块应注意的问题
第一、try、catch、finally三个语句块均不能单独使用,三者可以组成 try…catch…finally、try…catch、try…finally三种结构,catch语句可以有一个或多个,finally语句最多一个。
第二、try、catch、finally三个代码块中变量的作用域为代码块内部,分别独立而不能相互访问。如果要在三个块中都可以访问,则需要将变量定义到这些块的外面。
第三、多个catch块时候,只会匹配其中一个异常类并执行catch块代码,而不会再执行别的catch块,并且匹配catch语句的顺序是由上到下。
3、throw、throws关键字
throw关键字是用于方法体内部,用来抛出一个Throwable类型的异常。如果抛出了检查异常,则还应该在方法头部声明方法可能抛出的异常类型。该方法的调用者也必须检查处理抛出的异常。如果所有方法都层层上抛获取的异常,最终JVM会进行处理,处理也很简单,就是打印异常消息和堆栈信息。如果抛出的是Error或RuntimeException,则该方法的调用者可选择处理该异常。有关异常的转译会在下面说明。
throws关键字用于方法体外部的方法声明部分,用来声明方法可能会抛出某些异常。仅当抛出了检查异常,该方法的调用者才必须处理或者重新抛出该异常。当方法的调用者无力处理该异常的时候,应该继续抛出,而不是囫囵吞枣一般在catch块中打印一下堆栈信息做个勉强处理。下面给出一个简单例子,看看如何使用这两个关键字:

- public static void test3() throws Exception{
- //抛出一个检查异常
- throw new Exception(“方法test3中的Exception”);
- }
getCause():返回抛出异常的原因。如果 cause 不存在或未知,则返回 null。
getMessage():返回异常的消息信息。
printStackTrace():对象的堆栈跟踪输出至错误输出流,作为字段 system.err 的值。
2、 对于检查异常,如果不能行之有效的处理,还不如转换为RuntimeException抛出。这样也让上层的代码有选择的余地――可处理也可不处理。
3、 对于一个应用系统来说,应该有自己的一套异常处理框架,这样当异常发生时,也能得到统一的处理风格,将优雅的异常信息反馈给用户。

- public class DAOException extends RuntimeException {
- //(省略了部分代码)
- public DAOException(String message, Throwable cause) {
- super(message, cause);
- }
- }

图中的三条线标识转换的方向,分三种情况:

- try {
- lowLevelOp();
- } catch (LowLevelException le) {
- throw (HighLevelException)
- new HighLevelException().initCause(le);
- }
五、 设计一个高效合理的异常处理框架

六、 Java异常处理总结
2、 Java异常类来自于Java API定义和用户扩展。通过继承Java API异常类可以实现异常的转译。
深入探索 高效的Java异常处理框架的更多相关文章
- java异常处理机制
本文从Java异常最基本的概念.语法开始讲述了Java异常处理的基本知识,分析了Java异常体系结构,对比Spring的异常处理框 架,阐述了异常处理的基本原则.并且作者提出了自己处理一个大型应用系统 ...
- Java Executor框架使用
Java Executor框架是Jdk1.5之后推出的,是为了更加方便的开发多线程应用而封装的框架: 相比传统的Thread类,Java Executor使用方便,性能更好,更易于管理,而且支持线程池 ...
- Java 异常处理机制和集合框架
一.实验目的 掌握面向对象程序设计技术 二.实验环境 1.微型计算机一台 2.WINDOWS操作系统,Java SDK,Eclipse开发环境 三.实验内容 1.Java异常处理机制涉及5个关键字:t ...
- Java:使用 Java 开发的一个异常处理框架
背景 这篇文章介绍的异常处理思路不错,本文试图给出一种具体实现,当然可能和作者的思路有所不同. 框架地址:https://github.com/happyframework/HappyFramewor ...
- Java探索之旅(16)——异常处理
1.异常与异常处理 在<java编程思想>中这样定义 异常:阻止当前方法或作用域继续执行的问题.虽然java中有异常处理机制,但是要明确一点,决不应该用"正常"的态度来 ...
- Java异常处理和设计
在程序设计中,进行异常处理是非常关键和重要的一部分.一个程序的异常处理框架的好坏直接影响到整个项目的代码质量以及后期维护成本和难度.试想一下,如果一个项目从头到尾没有考虑过异常处理,当程序出错从哪里寻 ...
- Java异常处理和设计【转】
Java异常处理和设计 在程序设计中,进行异常处理是非常关键和重要的一部分.一个程序的异常处理框架的好坏直接影响到整个项目的代码质量以及后期维护成本和难度.试想一下,如果一个项目从头到尾没有考虑过异常 ...
- 【译】快速高效学习Java编程在线资源Top 20
想要加强你的编程能力吗?想要提升你的 Java 编程技巧和效率吗? 不用担心.本文将会提供快速高效学习 Java 编程的 50 多个网站资源: 开始探索吧: 1.MKyong:许多开发者在这里可以找到 ...
- 快速高效学习Java编程在线资源Top 20(转载)
想要加强你的编程能力吗?想要提升你的 Java 编程技巧和效率吗? 不用担心.本文将会提供快速高效学习 Java 编程的 50 多个网站资源: 开始探索吧: 1.MKyong:许多开发者在这里可以找到 ...
随机推荐
- R语言学习笔记(十六):构建分割点函数
选取预测概率的分割点 cutoff<- function(n,p){ pp<-1 i<-0 while (pp>=0.02) { model.predfu<-rep(&q ...
- [BZOJ2809][Apio2012]dispatching(左偏树)
首先对于一个节点以及它的子树,它的最优方案显然是子树下选最小的几个 用左偏树维护出每棵子树最优方案的节点,记录答案 然后它的这棵树可以向上转移给父节点,将所有子节点的左偏树合并再维护就是父节点的最优方 ...
- 使用localStorage,sessionStorage,cookie等存储
Web 存储 API 提供了 sessionStorage (会话存储) 和 localStorage(本地存储)两个存储对象来对网页的数据进行添加.删除.修改.查询操作. 特点: localStor ...
- 谷歌面试官经典作品(CTCI)目录
1.1 判断一个字符串中的字符是否唯一 1.2 字符串翻转 1.3 去除字符串中重复字符 1.8 利用已知函数判断字符串是否为另一字符串的子串 2.1 从链表中移除重复结点 2.2 实现一个算法从一个 ...
- 为什么在默认情况下无法修改被block捕获的变量? __block都做了什么?
默认情况下,block里面的变量,拷贝进去的是变量的值,而不是指向变量的内存的指针.使用__block修饰后的变量,拷贝到block里面的就是指向变量的指针,所以我们就可以修改变量的值.
- 【WPF】 布局篇
[WPF] 布局篇 一. 几个常用且至关重要的属性 1. Width,Height : 设置窗体,控件宽高. 这里注意,WPF是自适应的, 所以把这2个属性设置 Auto, 则控件宽高会自动改变. 2 ...
- oracle 游标例子
CREATE OR REPLACE PROCEDURE PRC_WAP_ACTIVEUSERS(RETCODE OUT VARCHAR2) /***************************** ...
- ES5新增数组方法(4):every
检查数组元素的每个元素是否符合条件. // 数组中的元素全部满足指定条件返回true let arr = [1, 3, 5, 7, 9]; console.log(arr.every((value, ...
- 第三篇 Postman之 Tests(后置处理器,断言)
第二篇里讲了手动设置全局变量及局部变量的方法,但是这有一个缺点,就是每次测试之前,都需要获取相关变量值,手动再填写更新到对应的全局变量或者局部变量里,这对于想进行自动化执行的人或者懒人就不太友好了,本 ...
- ubuntu12.04停留在grub界面问题
修改ubuntu 12.04 停留在grub界面的步骤: 1. 在/etc/default/grub配置文件中, 添加一项GRUB_RECORDFAIL_TIMEOUT: GRUB_TIMEOUT=2 ...