毕业设计(论文)-基于Java的异常处理技术及其应用_第1页
毕业设计(论文)-基于Java的异常处理技术及其应用_第2页
毕业设计(论文)-基于Java的异常处理技术及其应用_第3页
毕业设计(论文)-基于Java的异常处理技术及其应用_第4页
毕业设计(论文)-基于Java的异常处理技术及其应用_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、目目 录录一 引言 .1二 关于 JDK 和 Java 异常 .2(一)Java 异常定义 .2(二)Java 中的异常类 .2(三)Java 语言规范对异常处理的要求 .4三 Java 异常的处理机制 .4(一)Java 异常处理机制具体实现 .4(二)Java 中异常发生的原因 .6(三)Java 异常处理的优点 .6四 Java 异常处理技术及其应用 .8(一)抛出异常 .8(二)捕获异常 .8(三)堆栈帧 .9(四)自定义异常 .11(五)关于图形界面程序的异常捕获.12五 Java 异常处理基本原则 .14(一)不要忽略已检查型异常 .14(二)不要一次捕获所有的异常 .15(三)使

2、用 finally 块释放资源 .16(四)异常不能影响对象的状态 .17(五)注意丢失(或忽略)的异常.17(六)不要同时使用异常机制和返回值来处理异常.20(七)不要让 try 块过于庞大 .21六 结束语 .21致谢 .21参考文献 .22附录、源代码 .221基基于于J Ja av va a的的异异常常处处理理技技术术及及其其应应用用摘摘 要要 本文以Java软件开发工具箱 JDK1.5.0作为环境,通过与一些编程语言的错误处理相比较,介绍了Java中异常处理技术的由来 、定义、规范和Java内建的异常类,讨论了Java中异常产生的原因 、实现,还对Java异常处理机制的优点进行了简述

3、,就 Java异常处理技术从抛出异常、捕获异常、堆栈帧、自定义异常、 图形界面程序 异常捕获五个方面进行了讨论 。本文还就Java异常处理技术的应用做了一些探讨 ,试图从软件开发者的角度说明Java异常处理技术在开发中一些有价值的应用。关键词 Java语言 Java异常处理 JVM 一 引言在程序设计中,尽管编 写检查和处理错误的程序代码很乏味,并且它们使程序源代码显得冗长,但是,错误检测和处理仍是任何健壮应用程序最重要的组成部分之一。传统的异常处理多采用返回值来标识程序 中出现的异常情况 ,这是程序员熟悉的一种方式,但却有很多缺点。首先 ,一个 API(Application Program

4、ming Interface 应用编程接口) 可以返回任意的返回值 ,而这些返回值本身并不能解释 是否代表一个异常情况发生 或者发生异常的具体情况 ,需要调用 API 的程序自己判断并解释返回值的含义。其次 ,它并没有一种机制来保证异常情况一定会得到处理 ,调用程序可以简单地忽略该返回值 ,从而需要调用API 的程序员记住去检测返回值并处理异常情况。这种方式还让程序代码变得晦涩冗长, 当进行容易出现异常情况的处理时,比如: I/O 操作,程序中会出现 很大的部分用于处理异常情况的 switch 分支,程序代码的可读性变得很差。相对于传统异常处理方式的缺点 ,Java异常处理机制提供了很好的解决

5、方案。 Java异常处理使开发人员不用编写特殊代码检测返回值就能够很容易地检测错误,并且把异常处理代码和异常产生代码明确地分开, 通过抛出Java预定义或者自定义的异常 ,能够表明程序中出现了什么样的异常情况1;而且Java的语言机制保证了异常一定会得到恰当的处理 ,合理地使用异常处理机制 ,会让程序代码更清晰 。 2二 关于 JDK 和 Java 异常(一)Java 异常定义 早期的编程语言(比如 C语言)没有异常处理,通常是遇到错误返回一个特殊的值或设定一个标志,并以此判断是不是有错误产生。随着系统规模的不断扩大,这种错误处理已经成为创建大型可维护程序的障碍了。于是在一些语言中出现了异常处

6、理机制,比如在Basic中的异常处理语句 “on error goto”,而Java则是在C+基础上建立了新的异常处理机制。Java通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。这种机制为复杂程序提供了强有力的控制方式。同时这些异常代码与“常规”代码分离,增强了程序的可读性,编写程序时也显得更灵活。 在编译时没有问题的 Java源程序,在运行期可能还会发生错误,这种错误就称为异常(Exception) 。异常也可认为是程序运行过程中违背正常指令流而产生的事件2。(二)Java 中的异常类在 Java 中,所有的异常都是以类对象的形式存在的。每个异常都是Throw

7、able 类或其子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理3。Throwable是所有异常的基类 ,程序中一般不会直接抛出 Throwable对象,Exception和Error是Throwable的子类,Exception下面又有RuntimeException和一般的Exception两类。可以把Java异常分为三类:第一类是Error,Error表示程序在运行期间出现了十分严重、不可恢复的错误 ,在这种情况下应用程序只能终止运行 ,例如Java虚拟机(JVM)出现错误。在 EJB(Enterprise Jav

8、aBean)中将此类归为 JVM 异常,这种类型的异常由 JVM 抛出。Error是一种uncheckedException(未检查型异常) ,编译器不会检查 Error是否被处理,在程序中不用捕获Error类型的异常;一般情况下,在程序中也不应该抛出 Error类型的异常。第二类是RuntimeException,在EJB也称为系统异常。 RuntimeException是一种未检查型异常,即表示编译器不会检查程序是否对 RuntimeException作了处理,在程序中不必捕获未检查型异常,也不必在方法体声明抛出 RuntimeException类。RuntimeException发生的时

9、候,表示程序中出现了编程错误 ,所以应该找出错误修改程序 ,而不是去捕获3RuntimeException。 图 21 Java 异常类层次图第三类是一般的 checkedException, 即已检查型异常。在EJB中称为应用程序异常。已检查型异常是在编程中使用最多的 异常,所有继承自Exception并且不是RuntimeException的异常都是已检查型异常,如图2-1中为Java异常的类层次图 。Java 系统包 java.lang、java.util、java.io 和 中都声明有标准异常类。这些异常类以未检查型异常类和已检查型异常类可分为如下:已检查型异常类主要有:(1)在 ja

10、va.lang 中:ClassNotFoundException:指定名字的类或接口没有被发现。CloneNotSupportedException:克隆一个没有实现 Cloneable 接口的类。IllegalAccessException:试图使用给出了完全路径信息的字符串加载一个类 ,但当前正在执行的方法无法访问指定的类 ,原因是该类不是 public 类或是在另一个包中。InstantiationException:试图使用 Class 的 newInstance 方法创建一个对象实例 ,但是,指定的对象没有被实例化 ,因为它是一个接口、抽象类或者一个数组。InterruptedExc

11、eption:当前的线程正在等待 ,而另一个线程则使用了 Thread 的interrupt 方法中断了当前线程。(2)在 Java.io 中:IOException:申请 I/O 操作没有成功。EOFException:在输入操作正常结束前遇到了文件结束符。FileNotFoundException:在文件系统中,没有找到由文件名字符串指定的文件。InterruptedIOException 当前线程正在等待 I/O 操作的完成,而另一个线程使用 threadThrowableErrorExceptionIOExceptionRuntimeException4的 interrupt 方法中断

12、了当前线程。未检查型异常类主要有:(1)在 java.lang 中:ArithmeticException:表示遇到了算术的异常问题 ,例如 0 作为除数。ArrayStoreException:试图把与数组类型不相符的值存入数组。ClassCastException:试图把一个对象的引用强制转换为不合适的类型。InderOutOfBoundsException:数组的下标越界。NullPointerException:试图使用一个空的对象引用。SecurityException:检测到了违反安全的行为。(2)在 java.util 中:EmptyStaceException:试图访问一个空堆

13、栈中的一个元素。NoSuchElementException:试图访问一个空向量中的元素。(三)Java 语言规范对异常处理的要求Java语言规定必须对 已检查型异常 作处理,编译器会对此作检查 ,要么在方法体中声明抛出已检查型异常,要么使用catch语句捕获已检查型异常 进行处理,不然不能通过编译2。已检查型异常用于以下环境:(1)该异常发生后是可以被恢复的 ,如一个Internet连接发生异常被终止后 ,可以重新连接再进行后续操作。(2)程序依赖于不可靠的外部条件 ,该依赖条件可能出错 ,如系统I/O。(3)该异常发生后并不会导致程序处理错误 ,进行一些处理后可以继续后续操作。Java语言

14、规范中将任何 Error的子类以及RuntimeException的子类都称为未检查 型异常。而其它异常都称为已检查 型异常。三 Java 异常的处理机制(一)Java 异常处理机制具体实现在Java程序运行出现异常时,发生异常的程序段要抛出异常 ,而运行系统负责寻找一段代码来处理异常。 Java语言中,创建一个异常对象并将它交给运行系统称为抛出一个异常 ,又称为异常抛出。5在 Java 中,一个方法要抛出异常 ,必须遵循一定的规定 ,即所谓的“异常规范” 。异常规范采用了一个额外的关键字 :throws。要使方法抛出异常,应在方法声明中,位于参变量列表的后面(即 throws 后面)列举全部

15、潜在的异常类型 。假若 Java 中的某方法可能抛出一个异常 ,但程序中没有对其进行控制 ,编译器会侦测到这个情况,通知程序员必须在此方法内进行异常控制 ,或者从方法里抛出一个异常。通过遵守异常规范,Java 可在编译期保证异常处理的正确性。当Java抛出一个异常 ,程序将从导致异常的代码处跳出 ,JVM检测寻找和try关键字匹配的处理该异常的 catch块,如果找到,将控制权交到catch块中的代码,然后继续往下执行程序, 如果没有找到处理该异常的 catch块,try块中发生异常的代码不会被重新执行 ,在所有的finally块代码被执行和当前线程的所属的 ThreadGroup的uncau

16、ghtException方法被调用后,遇到异常的当前线程被终止。Java异常处理的语句形式如下 :try/正常执行的代码可能产生异常throw(异常类1 e,异常类2 e,异常类n e)catch(异常类1 e)/异常类1的处理代码catch(异常类2 e)/异常类2的处理代码catch(异常类n e)/异常类n的处理代码finally/执行清除工作的语句6Java程序运行在try块中,如果产生了异常 ,则不再运行try块下面的语句,而直接进入catch块中,寻找第一个与之匹配的异常类型。 try/catch语句会自动在 try块后面的各个catch块中,找出与该异常类相匹配的参数。 如果该参

17、数符合以下三个条件之一时 ,则认为这个参数与产生的异常相匹配4。(1)参数与产生的异常属于同一个类。(2)参数是产生异常的父类。(3)参数是一个接口,产生的异常实现了这一个 接口。当产生的异常找到了第一个与之相匹配的参数时 ,就执行这一参数的 catch块中的Java代码。执行完catch块后,程序恢复执行,但不会回到异常发生处继续执行而是执行try/catch结构后面的代码。finally语句可以说是为 异常处理事件提供的一个清理机构。一般是用来关闭文件或者释放其他的系统资源作为 try/catch/finally结构的一部分,可以没有finally块。如果存在finally块,无论try块

18、中是否发生异常 ,是否执行过catch块,都要执行finally块。用finally块的一个好处,就是把方法中所有清除状态和关闭系统文件的语句放在一起 ,不但避免代码的重复 ,更是减少出现遗漏语句 ,对于程序以后的修改也较为集中和方便。(二)Java 中异常发生的原因异常发生有三种原因 :(1)Java虚拟机检测到了非正常的执行状态 ,这些状态可能由三种因素之一引起 :表达式的计算违背了 Java语言的语义,例如:数组越界、除数为 0等。在载入和链接 Java程序时出现错误 。超出了系统的资源限制 ,例如使用了太多的内存这些无法预知的异常。(2)Java程序代码中的throw语句被执行。(3)

19、发生异步异常 ,其可能的原因有 Thread类的stop方法被调用;JVM内部发生错误;运行时库出现了内部错误 等。(三)Java 异常处理的优点在面向过程的传统语言中对 程序中可能出现的错误一般采取 :查错、报错和排错的处7理错误代码和常规代码混杂在一起的方法。比如在 C语言(面向过程的一种编程语言)中输出流的处理伪代码是:建立一个文件输入流 ;if(建立不成功) 报错;处理错误;else 从输入流中读入一个字符 ; if(读入不成功) 报错;处理错误;关闭该文件的输入流if(关闭不成功) 报错;处理错误; else else 经过这样的处理 ,程序可以保证正 常地运行。但是程序的每一步都要

20、考虑是否会发生错误,出现了错误又该如何处理的问题。这不但使程序 代码的行数大大 增加,而且,处理错误代码和正常代码混杂在一起 ,使程序流程变得十分复杂 ,不利于阅读。此外 ,它对于同一类型的错误也不方便进行统一的处理。于上面等价实现地 面向对象语言处理异常的伪代码为 :try 建立一个文件输入流 ;读取一个字符 ;.;关闭该输入流 ;catch( 文件输入流打开失败 ) 报错;处理错误;.; catch( 读入字符失败 ) 报错;处理错误;.面向对象语言的异常处理 对于面向过程语言 处理错误的方法有三种好处 :其一将处理错误代码和正常代码分离 ;其二能够将异常沿着调用堆栈向上传播 ;其三能按异

21、常类型和异常对象分组。8四 Java 异常处理技术及其 应用(一)抛出异常如果有一个现成 (或者已定义) 的异常可以使用,则抛出异常很容易。只要满足以下三点:(1)找到一个恰当的异常类(2)构造一个该类的实例(3)抛出该实例比如我们经常遇到 IOException异常发生,其中它的一个子类是 EOFException,就是描述在输入过程中碰到一个未预期的文件结尾标志,我们抛出该异常的方法如下:throw new EOFException ( );或者这样:EOFException e = new EOFException ( );throw e ;(二)捕获异常 要想捕获一个异常,需要设置一个

22、 try/catch的代码块。try块的最简单形式如下: try codemore codecatch (ExceptionType e ) handler for this type如果try块内的任何代码抛出了由 catch块中指定的异常,则程序跳过 try块中的其它代码,程序执行 catch块中的处理代码。假如 try块没有任何代码抛出异常,那么程序会直接跳过catch块的内容。当然,可以在 try块同时捕获多个异常,并分别对每种类型加以不同的处理。9(三)堆栈帧在JDK1.4前,通过使用 Throwable类的printStacktrace方法来获得堆栈结构的文本描叙。现在,可以通过调

23、用 getStackTrace方法来获得一个 StackTraceElement对象的数组,通过研究该数组,就可以分析程序运行情况。例如:Throwable t = new Throwable ( );StackTraceElement frames = t.getStackTrace ( );For ( int i= 0;iframes.length;i+) 使用StackTraceElement类提供的方法获取文件名以及当前执行的代码行行号的方法,同样,它还提供获取类名 、方法名的方法。而 toString方法可以产生一个格式化字符串,其中包含那些获得的信息。以下程序StackTest.j

24、ava输出一个递归调用方法的堆栈情况。import java.util.*;import javax.swing.*;public class StackTest /* 返回 n! = 1 * 2 * . . . * n 的结果 */ public static int factorial (int n) System.out.println (factorial ( + n + ): ) ; Throwable t = new Throwable( ); StackTraceElement frames = t.getStackTrace(); for ( int i = 0 ;i fram

25、es.length; i+ ) System.out.println( frames i ); int r ; if (n = 1) r = 1; else r = n * factorial(n - 1); / 递归调用factorial()方法 System.out.println(return + r); return r; 10 public static void main(String args) String input = JOptionPane.showInputDialog( 请输入一个整数 : ); int n =Integer.parseInt(input); fact

26、orial(n); System.exit( 0 ); /退出程序 由于需要从标准输入中获取整数数字, Integer.ParseInt(input)方法可能会产生java.lang.NumberFormatException异常。运行程序时界面:图31 输入界面如果我们要实现递归方法 factorial(3),通过getStackTrace方法可以查看程序运行的过程。其结果为如下: 图32 递归方法factorial(3)的输出结果而这个程序可能产生的一个异常是 NumberFormatException异常。当异常产生后,JVM调用该异常处理。其运行界面如下:11图33 输入一个产生异常的

27、数据返回到控制台的结果为描述该异常:图34 输入异常数据时在控制台产生的结果(四)自定义异常由于在 Java 中,异常也被看成是对象 ,而且异常和一般的对象没有什么不同。因此 ,任何类都可以定义它自己的异常 ,并用 throw 语句引发它们。其中 ,throw 语句由带有一个对象的关键字 throw 组成,这个对象应该是 Exception 或其子类的一个实体对象。要注意的是,当执行了一条 throw 语句后,就不会执行该语句之后的任何代码了。通常每个异常类提供一个默认的构造器以及一个包含详细信息的构造器。使用Throwable 的 toString 方法会输出该详细信息,这个方法对代码调试是

28、很有用处。例如创建这样的异常类:class FileFormatException extends IOException public FileFormatException ( ) public FileFormatException ( ) super ( gripe) ; 12String readData ( BufferedReader in ) throws FileFormatException while ( ) if ( ch=-1) /EOF 标记,即文件结尾 if (nlen) throw new FileFormatException ( ); /抛出自定义的异常类

29、FileFormatException return s; (五)关于图形界面程序的异常捕获对于一个非图形界面的程序而言,如果一个异常没有被捕获,则程序会终止运行并且在控制台输出一条包含异常类型以及堆栈内容的信息。而对于具有图形界面的程序(包含applet以及应用程序) ,也会输出这些错误信息,但是程序会返回用户界面外层循环中去。下面我们从一个有趣的程序 -颜色调和板来讨论图形界面程序处理异常的情况。在SwingColorTest.java(源代码见附录) 中,程序可以根据我们输入红色 、绿色、蓝色(RGB) 、亮度、饱和度和色度值来调节颜色。整个程序除了可能会产生RuntimeExcepti

30、on异常外,这个程序还会产生 NumberFormatException异常。当然这是已检查型异常。下面我们来看它在 JVM中的运行情况:图41 输入正常数据时的颜色调和板13当我们改变”红色”值为非法的一个输入,比如: “AB”时,其运行结果为如下:图42 输入一个产生异常的数据颜色未变化,好像程序发生逻辑错误似的(没有按照我们希望的去运行)其实程序已将控制权转到控制中心去了,这个图形还处于初始化阶段(在输入“AB”前) 。在控制中心我们发现如下一些异常发生描述:图43 异常产生后返回到控制台的说明 这说明发生了NumberFormatException(数字格式异常)异常后,并没有继续往下

31、执行代码。由于数字格式异常为已检查型异常,直接调用系统的方法处理了。JVM报告程序发生了数字格式异常产生,并将其具体的情况报告给用户。但是,是不是这个程序不能再接受正常的输入数据运行呢?还是必须要重新启动才能运行?我们将“红色”值由“AB”改为“200”后发现颜色改变,这说明该程序还能运行。结果如下图:图44 将产生异常的输入数据更改后的颜色调和板可见当输入了正常的数据后,程序就像第一次运行一样,可以正确的显示颜色了。我14们得到的结论是:部分 Java图形界面程序发生异常后不需要重新初始化,依旧可以运行,但必须不再有异常发生。五 Java 异常处理基本原则合理使用Java异常机制可以使程序健

32、壮而清晰 ,但是,Java异常处理机制 也常常会被错误地使用,下面就讨论一些关于 使用异常的原则:(一)不要忽略已检查型异常注意下面的代码:try method1(); /method1抛出Exception Acatch(Exception A) /捕获Exception Ae.rintStackTrace( ); /打印捕获异常上面的代码似乎没有什么问题 ,捕获异常后将异常打印 ,然后继续执行。事实上在catch块中对发生的异常情况并没有作任何处理。虽然程序能够继续执行,但是由于这里的操作已经发生异常 ,将会导致以后的操作不能按照预期的情况发展下去 ,可能导致两个结果 。一种情况是这里的异

33、常导致在程序中别的地方抛出一个异常 ,这会使程序员在调试时感到迷惑,因为新的异常抛出的地方并不是程序真正发生问题的地方 ,也不是发生问题的真正原因。另外一种情况程序继续运行 ,并得出一个错误的输出结果 ,这种问题更加难以捕捉 ,因为很可能把它当成一个正确的输出。那么应该如何处理呢 ?一般有四个选择:处理异常,进行修复以让程序继续执行 ;重新抛出异常,在对异常进行分析后发现这里不能处理它 ,那么重新抛出异常 ,让调用者处理 ;将异常转换为用户可以理解的自定义异常再抛出 ,这时应该注意不要丢失原 始异常信息;不要捕获异常。因此,当捕获一个未检查型异常 时,必须对异常进行处理 ;如果认为不必要在这里

34、作处理,就不要捕获该异常 ,在方法体中声明方法抛出异常 ,由上层调用者来处理该异常。15(二)不要一次捕获所有的异常我们常见如下关于异常处理的代码 :trymethod1(); /method1抛出ExceptionAmethod2(); /method2抛出ExceptionBmethod3(); /method3抛出ExceptionCcatch(Exception e) /捕获所有异常 代码中使用一个 catch子句捕获了所有异常 ,看上去很简洁 ,一个代码段就捕获了全部的异常。但是这里有两个潜在的缺陷 ,一是对try块中抛出的每种 异常,很可能需要不同的处理和恢复措施 ,而由于这里只有

35、一个 catch块,分别处理就不能实现。二是 try块中还可能抛出RuntimeException,代码中捕获了所有可能抛出的 RuntimeException而没有作任何处理,掩盖了编程的错误 ,会导致程序难以调试。我们应该处理为以下的代码 :trymethod1();method2();method3();catch (ExceptionA e)/分别捕获和处理三种异常 catch (ExceptionB e) catch (ExceptionC e) 16(三)使用 finally 块释放资源关键字finally保证程序使用任何方式离开 try块,finally块中的语句都会被执行。当程

36、序中使用了外界资源 ,如数据库连接、文件等 ,将释放这些资源的代码写入 finally块中是很好的处理方式。必须注意的是,在finally块中不能抛出异常。 Java异常处理机制保证在任何情况下必须先执行finally块然后再离开 try块,因此在try块中发生异常的时候 ,Java虚拟机先转到finally块执行finally块中的代码,finally块执行完毕后 ,再向外抛出异常。如果在finally块中抛出异常,try块捕捉的异常就不能抛出 ,外部捕捉到的异常就是 finally块中的异常信息,而try块中发生的真正的异常堆栈信息则丢失了。Connectioncon = null;try

37、 con=dataSource.getConnection();/抛出数据库异常catch(SQLException e ) /捕获异常进行一些处理后再将数据库异常抛出给调用者处理throw e;finally try con.close();catch(SQLException e) e.printStackTrace();由于con为null,finally块有异常发生,从而使try块中发生的异常堆栈信息丢失。其调用者会得到如下信息:Java.lang.NullPointerExceptionat17myPackage.MyClass.method1(methodl.Java:266)(四

38、)异常不能影响对象的状态异常产生后不能影响对象的状态 ,这是异常处理中的一条重要规则。 一个函数中发生异常后,对象的状态应该和调用这个函数之前保持一致 ,以确保对象处于正确的状态中。如果对象是不可变对象 (指调用构造函数创建后就不能改变的对象 ),即创建后没有任何方法可以改变对象的状态 ,那么异常发生后对象状态肯定不会改变。如果是可变对象 ,必须在编程中注意保证异常不会影响对象状态。有三个方法可以 做到异常不能影响对象地状态 :(1)将可能产生异常的代码和改变对象状态的代码分开 ,先执行可能产生异常的代码 ,如果产生异常,就不执行改变对象状态的代码。(2)对不容易分离产生异常代码和改变对象状态

39、代码的方法 ,定义一个recover方法,在异常产生后调用 recover方法修复被改变的类变量 ,恢复方法调用前的类状态。(3)在方法中使用对象的拷贝 ,这样当异常发生后 ,被影响的只是拷贝 ,对象本身不会受到影响。(五)注意丢失(或忽略)的异常 在程序设计中,可以丢失(忽略)一些异常,但是为了以后更好地维护代码,最好不要丢失异常。比如 下面的代码:public void method2( ) trymethod1( ); /method1进行了数据库操作catch( SQLException e )/捕获数据库异常后将该异常封装为18/MyException后重新抛出throw new M

40、yException(“发生了数据库异常 : +e.getMessage);public void method3( ) trymethod2( ); /调用method2(),抛出MyExceptioncatch (MyException e)e.printStackTrace( );在method2的代码中,try块捕获method1抛出的数据库异常 SQLException后,抛出了新的自定义异常MyException。这段代码是 似乎没有什么问题,但在控制台的输出却是:MyException:发生了数据库异常 :对象名称“MyTable无效atMyClass.method2(MyCla

41、ss.Java:232)atMyClass.method3(MyClass.Java:255)原始异常SQLException的信息丢失了 ,这里只能看到 method2里面定义的MyException的堆栈情况,而method1中发生的数据库异常的堆栈则看不到。如何排错呢?只有在method1的代码行中一行行去寻找数据库操作语句 。JDK的开发者们也意识到了这个情况 ,在JDK1.4.1中,Throwable类增加了两个构造方法, public Throwable ( Throwablecause)和public Throwable ( Stringmessage, Throwablecau

42、se ),在构造函数中传入的原始异常堆栈信息将会在 printStackTrace方法中打印出来。但 在JDK1.3中就只能靠程序员来实现打印原始异常堆栈信息了。实现过程也很简单 ,只需要在自定义的异常类中增加一个原始异常字段 ,在构造函数中传入原始异常 ,然后重载printStackTrace方法,首先调用类中保存的原始异常的 printStackTrace方法,然后再调用super.printStackTrace方法就可以打印出原始异常信息了。可以这样定义前面代码中出现的MyException类:public class MyException extends Exception19pub

43、lic SMException ( Throwable cause )/构造函数this.cause1=cause;public MyException ( Strings ,Throwable cause )super(s);this.cause1=cause;/重载printStackTrace方法,打印出原始异常堆栈信息public void printStackTrace()if(cause1!=null)cause1.printStackTrace();super.printStackTrace(s);public void printStackTrace(PrintStream s

44、)if(cause1!=null)cause1.printStackTrace(s); super.printStackTrace(s);public void printStackTrace( PrintWriter s )if(cause1!=null)cause1.printStackTrace(s);20super.printStackTrace(s);private Throwable cause1;(六)不要同时使用异常机制和返回值来 处理异常我们可能会使用类似下面一段代码 :trydoSomething( );catch(MyException e)if(e.getErrcode

45、=-1) if(e.getErrcode=-2) 假如过一段时间再来阅读这段代码 ,你很难弄明白程序的意思。混合使用 Java异常处理机制和返回值使程序的异常处理部分变得混乱 ,并难以理解。在程序中,如果有多种不同的异常情况 ,就应该定义多种不同的异常 ,而不要像上面代码那样。综合使用Exception和返回值。处理应该如下:try doSomething( );/doSomething()抛出MyExceptionA和MyExceptionBcatch(MyExceptionA e) /捕获异常分别进行处理 catch(MyExceptionB e) 21(七)不要让 try 块过于庞大有人

46、习惯用一个庞大的 try块包含所有可能产生异常的代码 ,这样有两个坏处 :一是阅读代码的时候,在try块冗长的代码中 ,不容易知道到底是哪些代码会抛出哪些异常 ,不利于代码维护;二是使用try捕获异常是以程序执行效率为代价的 ,将不需要捕获异常的代码包含在try块中,影响了代码执行的效率。 因此,在Java程序中最好将try块编写得简洁些。六 结束语Java是一种面向对象的程序设计语言 ,Java的异常处理机制非常出色。 Java中的所有异常都是从基础类 Throwable里继承而来的 ,所以可确保我们得到的是一个通用接口。丢弃一个错误的异常后 ,Java异常规范是在编译期间检查并执行的。被取

47、代的方法必须遵守那一方法的基础类的异常规范 。Java可丢弃指定的异常或者从指定异常衍生出来的其他异常。这样一来,运用try/catch/finally异常处理机制,最终得到的是更为 “健壮”的异常控制代码。 Java异常处理为大的程序项目带来很好的健壮性。当然,在写本论文时,由于对 Java的学习没达到深入、精通程度,掌握 Java异常处理技术也不是很全面,故而论文中对 Java图形程序的异常处理方面和 Java异常处理机制具体实现的讨论仍有不足之处有待以后改进。致谢参考文献1Bloch J.Effective. Java Programming Language Guide.北京:机械工业

48、出版社 ,2001.2Cay S.Horstmann .Core Java 2(第6版) .北京:机械工业出版社, 2004.3Rogers Cadenhead ,Laura Lemay.Teach Yourself Java 2 In 21days.北京:人民邮电出版社,2004.4朱福喜,唐晓军 .Java程序设计技巧与实例 .北京:人民邮电出版社, 2004.5谭浩强,程龙,杨海兰,吴功宜.Java编程技术.北京:人民邮电出版社, 2003.6彭晨阳.Java实用系统开发指南 . 北京:机械工业出版社, 2003.227Java 2 SDK1.5.0 Standard Edition D

49、ocumentation8http:/J 2 程序设计.北京:清华大学出版社, 2004.10Kalthy Sierra,Bert Bates.Java 2学习指南.北京:人民邮电出版社, 2004.11耿祥义.Java基础教程.北京:清华大学出版社, 2004.12朱福喜.Java程序设计技巧与开发实例 .北京:人民邮电出版社, 2004.13谢小乐.J2EE经典实例详解 .北京:人民邮电出版社, 2003.14Y.Daniel Liang.Java语言程序设计 (第三版).北京:机械工业出版社, 2005. 15Bruce Eckel.Java 编程思想. 北京:机械工业出版社, 2005

50、.附录、源代码 SwingColorTest.java的源代码:import java.awt.*;import java.awt.event.*;import javax.swing.*;public class SwingColorTest extends JFrame SwingColorControls RGBcontrols, HSBcontrols; JPanel swatch; public SwingColorTest() super(颜色调和板); setSize(400, 100); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE

51、); JPanel pane = new JPanel(); GridLayout grid = new GridLayout(1, 3, 5, 15); pane.setLayout(grid); /使用网格布局 swatch = new JPanel(); swatch.setBackground(Color.black); String rgbLabels = 红色, 绿色, 蓝色 ;23 RGBcontrols = new SwingColorControls(this, rgbLabels); String hsbLabels = 色调, 饱和度, 亮度 ; HSBcontrols

52、= new SwingColorControls(this, hsbLabels); pane.add(swatch); pane.add(RGBcontrols); pane.add(HSBcontrols); setContentPane(pane); pack(); setVisible(true); /main函数 public static void main(String arguments) JFrame frame = new SwingColorTest(); /RGB和HSB的相互转换 void update(SwingColorControls control) Colo

53、r c; / 从输入文本框中获得数据 int value = new int3; for (int i = 0; i 3; i+) valuei = Integer.parseInt(control.settingi.getText(); if ( (valuei 255) ) valuei = 0; control.settingi.setText( + valuei); if (control = RGBcontrols) c = new Color(value0, value1, value2); /转化为HSB24 float hsbValues = new float3; float

54、 HSB = Color.RGBtoHSB(value0, value1, value2,hsbValues); HSB0 *= 360; HSB1 *= 100; HSB2 *= 100; for (int i = 0; i 3; i+) HSBcontrols.settingi.setText(String.valueOf( (int)HSBi) ); else c = Color.getHSBColor( (float)value0 / 360, (float)value1 / 100, (float)value2 / 100 ); RGBcontrols.setting0.setText( String.valueOf(c.getRed() ); RGBcontrols.setting1

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论