`
hdy007
  • 浏览: 29818 次
最近访客 更多访客>>
文章分类
社区版块
存档分类

深入Java的异常机制

阅读更多

由于本文旨在探讨Java"异常机制"的深层原理,因此关于"异常"的使用方法都不做详细说明。首先看一段非常熟悉的用于打开一个文件的C程序段:

FILE *fp;

fp=fopen(filename,"rw");

if(fp==NULL){

printf("cannot open file\n");

exit(0);

}

在这段程序中,if条件语句中的一段用来处理没有找到指定文件,或者其它原因无法正 确打开指定文件。可是如果遇到一个责任心不强的程序员,他可能认为出现找不到文件的可能性很小,或者由于思路集中在程序功能的实现上而忘记了处理这种情 况。这时程序同样可以正确编译,而且一般情况下也不会出现问题。但此时这段程序可以肯定说是不够健壮的,而且一旦这段程序发生了错误也会让程序员很难发现 错误出在哪里。在C语言以及其它大多数高级语言中都可以举出很多这种例子。

也就是一个函数在使用的时候,可能会出现并没有达到这个函数的使用目的的情况,哪怕 在这段程序的特定使用环境下发生这种异常情况的可能性只有万分之一。常用处理的方法就是,程序员在需要使用某个函数时必须充分了解可能会有什么原因导致该 函数不能正确执行,然后加入相应的条件判断语句来进行处理。后面将有一个例子说明这个问题。

而Java的"异常机制"就是在处理上述问题中给了程序员非常简单而灵活的方式。一 般来说,其它高级语言主要是让函数使用者来关注该函数可能会出现的异常情况,而java则是把这件事情交给方法(和函数对应的概念,在Java中称方法) 的设计者来做。这对于方法的使用者来说带来的方便是不会因为责任心不强,或者办事丢三那四,会忘了在使用方法时处理可能发生的异常情况。而麻烦就是,在使 用一个可能会发生异常的方法时,绝对不能视而不见,而必须做出相应的处理。也就是说象上述C程序段中,如果忘了if程序块,这个程序甚至还能蒙过一个外行 上司,但当使用Java来完成这个功能时,只要用到的方法使用了"异常"机制,如果不对可能产生"异常"的方法进行相应处理,java编译器是不会让其通 过的。

一、"异常类"的组织形式

Java系统类中的方法产生的异常都被组织成"异常类"(还有Error类,不在本 文讨论范围),此方法和它相关的"异常类"通过throws关键字关联在一起,并且这些类都必须是Exception类的子类。任何一个自己开发的类的方 法中如果可能会产生某种异常,也可以将这种异常组织成一个"异常类",但这个"异常类"同样必须是Exception的子类,或孙子类等等。

例1:

/*isLegal于检查数据是否合法,当>0时视为合法,返回合法值,

*否则视为不合法,抛出"异常"。*/

int isLegal(int dt) throws LowZeroException//这种定义本文中均称为方法与"异常"通

{                  //过throws建立了关联

if(dt>=0){

return data;

}

else

throw new LowZeroException();

}

/*自已写的异常类,继承自Exception*/

class LowZeroException extends Exception

{

public LowZeroException(){

super();

}

}

仔细观察方法isLegal(),它体现出的最值得注意的特色是,它有两种方式的函 数出口,一种是通过return语句,返回的是方法本身定义的类型的实例,另一种是通过throw,返回的是"异常类"的对象实例,Java中称之为抛出 "异常"。对比一下C中如何处理同样的问题的:

int isLegal(int dt) {

if(dt>=0){

return data;

}

else

return -1;//通过一个特定值来表明出错

}

由于C只能通过return返回函数值,所以在处理异常情况时则可能通过以上方式来处理。当然这就要求isLegal()函数的使用者必须知道函数中使用返回值-1来表明出现不合法数据的情况。

对比这两种处理方法,可以知道java的"异常机制"把处理异常事件的职能和方法本身的职能通过两个不同出口分离开来。

所有这些"异常类"独立于它具体服务的方法被统一组织成一个类树。"异常机制"就好 比高校的后勤社会化一样,通过后勤社会化将学校的教学职能和学校的后勤保障分离开来,并且后勤集团的组织形式也是独立于学校主体的。事实证明,这种组织方 式不仅提高了服务效率,也提高了服务质量。整个Java体系中的"异常类"组织形式如图1所示:

在例1中的isLegal()方法如果在调用过程中没有能正常返回整形数,而是在"异常"产生点产生了"异常"对象,那么这个"异常"对象由谁来接收,并处理它呢?以下就来解答这个问题。

二、"异常"的处理过程

Java中由try…catch语法来处理"异常",将关联有"异常类"的方法包含 在try{}程序块中,catch(){}关键字可以使用形参,用于和方法产生的"异常"对象结合。当调用某个方法时,引起异常事件发生的条件成立,便会 抛出"异常",原来的程序流程将会在此方法处中断,然后try模块后紧跟的catch中的"形参"和此异常对象完成了结合,继而进入了catch模块中运 行。具体过程举例说明:

例2:

/*将关联有异常的方法包含在try模块中*/

int myMethod(int dt){

int data = 0;

try{

int data = isLegal(dt);

}catch(LowZeroException e){

System.out.println("发生数据错误!");

}

return data;

}

三、"异常"的处理方法

有两种方法处理"异常":第一种如例2,将含有"异常"出口的方法直接放到try块中,然后由紧随其后的catch块捕捉。第二种是不直接监听捕捉被引用方法的"异常",而是将这个"异常"关联传递给引用方法,同时监听捕捉工作也相应向上传递。

例3:

int myMethod2(int dt)

{

int data = 0;

try{

data = myMethod(dt)

}catch(LowZeroException e){

System.out.println("发生数据错误!");

e.printStackTrace();

}

return data;

}

int myMethod(int dt) throws LowZeroException

{

int data = isLegal(dt); //此处引用isLegal()方法,但并没有捕捉它的"异常"

return data;

}

从上例中可以看到方法myMethod()与它引用的方法isLegal()产生的 "异常"LowZeroException建立了关联,也就是完成了将"异常"关联的向上传递,此时的myMethod()方法体中虽然只有一个 return返回语句,但它事实上同样有两种方式的函数出口,一种是由return返回的整形值,另一种则是返回方法名中的throws关键字所指的"异 常类"的实例对象。相应的,监听捕捉的工作交给了上一层方法myMethod2()。同样的道理,myMethod2()也可以将"异常"通过 throws的关联继续向上传递。这样的话,一旦一个"异常"被捕捉到时,这个"异常"必有一个传递路径,而如果我们在捕捉点的catch程序块中加入 printStackTrace()方法,便能清楚的看到这个"异常"是怎样传递过来的。例如在例3如果有"异常"被捕捉到, e.printStackTrace()打印出来的结果将是:

LowZeroException:

at Example.isLegal

at Example myMethod

at Example.myMethod2

at Example main

从上结果中我们可以看到,从LowZeroException"异常"产生点,即包 含throw new LowZeroException();子句的方法开始,然后一直追溯到产生当前线程的方法(注意:printStackTrace()并不是追溯到捕捉 点结束,而是到产生当前线程的方法结束)。"异常"产生点产生的LowZeroException"异常"对象,首先被赋给了isLegal()关联的 LowZeroException类的无名引用,然后继续赋给myMethod()关联的LowZeroException类的无名引用,再继续赋给 myMethod2()中的catch块中的形参e,最后在这里被处理掉,这个"异常"对象随即消失。可以说,catch(){}就是"异常"对象的生命 终结点。

另外还要注意一点,方法与"异常"的关联可以一直向上传递,当传递到与main方法 关联后,即在main()方法的定义中使用了throws Exception,这时除了虚拟机没有其它方法能够引用main()方法,且在程序中可能看不到try…catch程序块,但并不会产生错误,因为此时 虚拟机会捕捉"异常",并且会默认的调用printStackTrace()方法打印出"异常"路径。总之只要一个方法关联了"异常",可以将这个"异常 "关联向上传递,但是最终必须使用catch来终止"异常",或者一直传递到main()方法交给Java虚拟机来结束"异常"对象的生命,否则是通不过 编译的。

四、使用"异常机制"的需要注意的几点

1.一个方法中可能会产生多种不同的异常,你可以设置多个"异常"抛出点来解决这个问题。

2."异常"对象从产生点产生后,到被捕捉后终止生命的全过程中,实际上是一个传值 过程,所以你可以根据需要,来合理的控制检测到"异常"的粒度。例如在例3中,如果你并不需要知道具体产生的是LowZeroException"异常 ",那么你可以使用"异常"的公共父类Exception来结合"异常"对象,即catch(Exception e){…}。同样在"异常"与方法关联的传递过程中,也可以根据需要控制关联"异常"的粒度,即throws后面跟上异常对象的父类名。

3."异常机制"中还有一种特殊情况――RuntimeException"异常类 "(见图1),这个"异常类"和它的所有子类都有一个特性,就是"异常"对象一产生就被Java虚拟机直接处理掉,即在方法中出现throw 子句的地方便被虚拟机捕捉了。因此凡是抛出这种"运行时异常"的方法在被引用时,不需要有try…catch语句来处理"异常"。

 

分享到:
评论

相关推荐

    深入理解java异常处理机制

    深入理解java异常处理机制,很详细的,去了,你们的!

    深入理解java异常处理机制Java开发Java经验技巧共

    深入理解java异常处理机制Java开发Java经验技巧共19页.pdf.zip

    Java中异常机制的深入研究

    本文旨在探讨Java的\"异常机制\",分别介绍了\"异常类\"的组织形式、\"异常\"的处理过程、\"异常\"的处理方法及使用\"异常机制\"的需要注意的问题。

    Java核心知识体系3:深入分析异常机制.pdf

    Java核心知识体系3:深入分析异常机制

    Java 异常处理面试集锦及答案20道

    本文提供了二十道常见的面试题,涵盖了Java异常处理的基本知识、异常类型、异常处理机制、关键字、异常链等方面。这些问题旨在考察候选人对Java异常处理的理解和应用能力。通过阅读本文,您将能够深入了解Java异常...

    深入理解java异常处理

    对java异常的工作过程进行详细解释,让初学者更好的掌握异常处理机制

    深入Java虚拟机(原书第2版).pdf【附光盘内容】

    《深入Java虚拟机(原书第2版)》,原书名《Inside the Java Virtual Machine,Second Edition》,作者:【美】Bill Venners,翻译:曹晓钢、蒋靖,出版社:机械工业出版社,ISBN:7111128052,出版日期:2003 年 9 ...

    深入理解java异常处理机制及应用

    本篇文章主要介绍了java异常处理机制及应用,异常处理机制是Java语言的一大特色。从异常处理的机制、异常处理的方法、异常处理的原则等方面介绍Java语言的异常处理技术,有兴趣的可以了解一下。

    深入理解java异常处理机制的原理和开发应用

    Java异常处理机制在日常开发中应用频繁,本篇文章主要在基础的使用方法上,更进一步的,如何更加合理的使用异常机制,希望可以对各位朋友能有所帮助。

    关于Java异常处理机制的深入理解.doc

    (网上找的,这个写的比较好,拿出来和大家共享一下)try…catch…finally恐怕是大家再熟悉不过的语句了,而且感觉用起来也是很简单,逻辑上似乎也是很容易理解。不过,我亲自体验的“教训”告诉我,这个东西可不是...

    深入Java Servlet网络编程

    1 Java中的异常处理机制 2. 4. 2 在Java Servlet中处理异常 2. 4. 3 向浏览器发送标准的HTTP错误 2. 4. 4 服务器端日志记录 2. 5 Servlet在n-层结构中的作用 第3章 会话育理 3. 1 使用传统方法进行会话管理...

    疯狂Java讲义+源代码

    本书深入介绍了Java编程的相关方面,全书内容覆盖了Java的基本语法结构、Java的面向对象特征、Java集合框架体系、Java泛型、异常处理、Java GUI编程、JDBC数据库编程、Java注释、Java的IO流体系、Java多线程编程、...

    疯狂Java讲义代码

    《疯狂Java讲义》深入介绍了Java编程的相关方面,全书内容覆盖了Java的基本语法结构、Java的面向对象特征、Java集合框架体系、Java泛型、异常处理、Java GUI编程、JDBC数据库编程、Java注释、Java的IO流体系、Java多...

    疯狂java讲义源代码

    本书深入介绍了Java编程的相关方面,全书内容覆盖了Java的基本语法结构、Java的面向对象特征、Java集合框架体系、Java泛型、异常处理、Java GUI编程、JDBC数据库编程、Java注释、Java的IO流体系、Java多线程编程、...

    疯狂Java讲义 第3版 PDF电子书下载 带书签目录 完整版.rar

    本书深入介绍了Java编程的相关方面,全书内容覆盖了Java的基本语法结构、Java的面向对象特征、Java集合框架体系、Java泛型、异常处理、JavaGUI编程、JDBC数据库编程、Java注释、Java的IO流体系、Java多线程编程、...

    深入java虚拟机中文第2版

    第5-20章深入描述了Java技术的内部细节,包括垃圾收集、Java安全模型、Java的连接模型和动态扩展机制、class文件、运算及流程控制等等,其中第6章和附录A-C安全可以作为class文件和指令集的参考手册。 前言 第1章 ...

    java基础.txt 百度云

    Java 异常机制解析 Java 集合与数据结构 JavaIO 流全解析 深入理解 Java 多线程 Java 网络编程 手动开发一个 Web 服务器 深入理解 Java 注解+反射 Java23 种设计模式 学会 Java 正则表达式 JDBC 详解 Java...

    《疯狂Java讲义》随书光盘

    本书深入介绍了Java编程的相关方面,全书内容覆盖了Java的基本语法结构、Java的面向对象特征、Java集合框架体系、Java泛型、异常处理、Java GUI编程、JDBC数据库编程、Java注释、Java的IO流体系、Java多线程编程、...

    疯狂Java讲义 第3版 完整版(Part3)

    本书深入介绍了Java编程的相关方面,全书内容覆盖了Java的基本语法结构、Java的面向对象特征、Java集合框架体系、Java泛型、异常处理、Java GUI编程、JDBC数据库编程、Java注释、Java的IO流体系、Java多线程编程、...

    疯狂java讲义 第17章

    本书深入介绍了Java编程的相关方面,全书内容覆盖了Java的基本语法结构、Java的面向对象特征、Java集合框架体系、Java泛型、异常处理、Java GUI编程、JDBC数据库编程、Java注释、Java的IO流体系、Java多线程编程、...

Global site tag (gtag.js) - Google Analytics