版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Java程序设计专业核心课程
精品课程1教学计划ORJECT了解Java程序异常类继承。了解Java中的多重捕获。理解Java语言中的释放资源。理解Java语言中的自定义异常类。1精品课程210.1Java异常Java提供了try(尝试)、catch(捕捉)、finally(最终)这三个关键字来处理异常。在处理各种异常时,需要用到对应的异常类,指的是由程序抛出的对象所属的类,常见的异常分类如下:(1)空指针异常(java.lang.NullPointerException)。发生此异常情况一般是字符串变量未初始化、数组未初始化、类对象未初始化,还有一种情况是当对象为空时并没有判断其是否为空值。为了避免这种情况,除了检查变量、数组、对象等是否初始化之外,如有必要则要加上判断是否为null的if语句。(2)指定的类不存在(java.lang.ClassNotFoundException)。出现这个错误的原因之一是缺包,这时只要下载并导入相应的包即可。但当已经把包导入的,又报了这种错误,这就需要人们在编辑器中进行调整设置了。在使用tomcat时,要先检查lib中是否导入了jar。3精品课程(3)字符串转换为数字异常(java.lang.NumberFormatException)。这个错误就是字符串中出现非数字型字符,转换为数字时发生异常。除此之外,如果字符串转换为数字(比如string转int、string转double)时超过了类型的范围,也会出现这个错误。解决该问题的方法就是在转换之前先对字符串进行检查。(4)数组下标越界异常(java.lang.IndexOutOfBoundsException)。数组下标越界异常是指取的数组元素在数组中并没有定义出来,比如定义了一个长度为5的数组a,当你想取a[6]元素时肯定会出错。解决这类问题就是要注意数组的长度,有时为了减少空间浪费,人们会使用动态数组构建方法,这时在对数组进行操作时建议先用length获取其数组长度,从而规避错误。(5)数学运算异常(java.lang.ArithmeticException)。除数为0时会报出该错误,解决方法是避免除数为0。可以将这个错误解读为“出现异常的运算条件”,除了除数为0的情况之外,可能还有其他的异常情况,可以根据具体情况进行分析。(6)没有访问权限(java.lang.IllegalAccessException)。属于权限问题,在程序访问某方法时注意一下访问权限即可(public/private),这种错误在使用package时容易发生。(7)方法的参数错误(java.lang.IllegalArgumentException)。在调用带有参数的方法时,请注意传递的参数是否正确。(8)数据类型转换异常(java.lang.ClassCastException)。在进行强制类型转换时容易发生该错误,在进行转换前要先对类型进行判别,规避错误。(9)文件未找到异常(java.lang.FileNotFoundException)。当程序试图打开一个不存在的文件进行读写操作时会报出该错误,通常由FileInputStream、FileOutputStream、RandomAccessFile的构造器声明发出,即使文件存在,但因某些原因无法访问,也会报出该错误。(10)数组存储异常(java.lang.ArrayStoreException)。假如在int型数组中存入string类型的变量,就会报错,解决方案是在存入对象时查明类型,或者在存入前先进行类型转换。(11)方法不存在异常(java.lang.NoSuchMethodException)。程序所要调用的方法不存在就会出现此异常,解决方法是不调用或者构造其方法。(12)文件已结束异常(java.lang.EOFException)。程序输入过程中遇到文件或流的结尾会引发该异常,此异常用于检查是否达到文件或流结尾。(13)实例化异常(java.lang.InstantiationException)。类创建新对象时无法通过构造器进行实例化引发的异常,解决方案是构造方法。(14)被中止异常(java.lang.InterruptedException)。通过其他线程的Thread的interrupt方法中止另一个线程时报出的错误,解决方法如下:①不做处理,直接抛出。②捕获异常,再次调用interrupt方法,将中断状态重新设置为true。4精品课程5精品课程(15)不支持克隆异常(java.lang.CloneNotSupportedException)。如果没有实现Cloneable接口便调用了clone方法,且报出该错误。若类不支持Cloneable接口,调用时也会出现该错误。解决方法是实现Cloneable接口。(16)输入输出异常(IOException)。该异常为Exception的一个分支,通常发生在文件的数据读写上。(17)错误(java.lang.Error)。所有错误的基类,用于标识严重的程序运行问题。通常是访问外部资源时出现一系列问题,解决方案也需要围绕访问外部资源这一重点展开。10.1.1 Java异常处理机制【例10.1】为了学习Java异常处理机制,首先了解下面的程序。//HelloWorld.java文件packagecom.a51work6;publicclassHelloWorld{publicstaticvoidmain(String[]args){inta=0;System.out.println(5/a);}}这个程序没有编译错误,但会发生如下的运行时错误。Exceptioninthread"main"java.lang.ArithmeticException:/byzeroatcom.a51work6.HelloWorld.main(HelloWorld.java:9)在数学上除数不能为0,所以程序运行时表达式(5/a)会抛出ArithmeticException异常,ArithmeticException是数学计算异常,凡是发生数学计算错误都会抛出该异常。程序运行过程中难免会发生异常,发生异常并不可怕,程序员应该考虑到有可能发生哪些异常,编程时应该捕获并进行处理,不能让程序发生终止,这就是健壮的程序。6精品课程10.1.2 异常类继承层次异常封装成为类Exception,此外,还有Throwable和Error类。异常类继承层次如图10-1所示。图10-1Java异常类继承层次10.1.3 Throwable类所有的异常类都直接或间接地继承于java.lang.Throwable类,在Throwable类中有以下几个非常重要的方法。(1)StringgetMessage():获得发生异常的详细消息。(2)voidprintStackTrace():打印异常堆栈跟踪信息。(3)StringtoString():获得异常对象的描述。【例10.2】接下来介绍Throwable类的使用,将例10.1中的代码修改成如下代码。//HelloWorld.java文件packagecom.a51work6;publicclassHelloWorld{publicstaticvoidmain(String[]args){inta=0;intresult=divide(5,a);System.out.printf("divide(%d,%d)=%d",5,a,result);}publicstaticintdivide(intnumber,intdivisor){try{returnnumber/divisor;}catch(Throwablethrowable){①System.out.println("getMessage():"+throwable.getMessage());②System.out.println("toString():"+throwable.toString());③System.out.println("printStackTrace()输出信息如下:");throwable.printStackTrace();④}7精品课程return0;}}其运行结果如下。getMessage():/byzerotoString():java.lang.ArithmeticException:/byzeroprintStackTrace()输出信息如下:java.lang.ArithmeticException:/byzeroatcom.a51work6.HelloWorld.divide(HelloWorld.java:17)atcom.a51work6.HelloWorld.main(HelloWorld.java:10)divide(5,0)=0将可以发生异常的语句System.out.println(5/a)放到try-catch代码块中,称为捕获异常,有关捕获异常的相关知识将会在下一节中详细介绍。在catch中有一个Throwable对象throwable(代码第①行),它是系统在程序发生异常时创建的,通过throwable对象可以调用Throwable中定义的方法。代码第②行是调用getMessage()方法来获得异常消息,输出结果是/byzero。代码第③行是调用toString()方法来获得异常对象的描述,输出结果是java.lang.ArithmeticException:/byzero。代码第④行是调用printStackTrace()方法打印异常堆栈跟踪信息。8精品课程堆栈跟踪信息从下往上是方法调用的顺序。首先JVM调用的是com.a51work6.HelloWorld类的main方法,接着在HelloWorld.java源代码第10行调用com.a51work6.HelloWorld类的divide方法,在HelloWorld.java源代码第17行发生了异常,最后输出的是异常信息。10.1.3 Error和ExceptionThrowable有两个直接子类:Error和Exception。1.ErrorError是程序无法修复的严重错误,程序员也根本无能为力,只能让程序终止。例如,JVM内部错误、内存溢出和资源耗尽等都属于Error。2.ExceptionException是程序可以修复的异常,它是程序员所能掌控的。例如,除零异常、空指针访问、网络连接中断和读取不存在的文件等。本章所讨论的异常处理就是对Exception及其子类的异常进行处理。10.1.4 受检查异常和运行时异常Exception类可以分为受检查异常和运行时异常。1.受检查异常受检查异常是除RuntimeException以外的异常类,它们的共同特点是编译器会检查这类异常是否进行了处理,即要么捕获(try-catch语句),要么不抛出(通过在方法后声明throws),否则会发生编译错误。受检查异常种类很多,如前文中介绍的日期解析异常ParseException就属于受检查异常。2.运行时异常运行时异常是继承RuntimeException类的直接或间接子类,往往是由程序员所犯错误而导致的,健壮的程序不应该发生运行时异常。运行时异常的共同特点是编译器不检查其是否进行了处理,也就是对于这类异常不捕获也不抛出,程序也可以编译通过。由于没有进行异常处理,一旦运行时异常发生就会导致程序的终止,这是用户不希望看到的。例如,例10.1中的ArithmeticException异常就属于RuntimeException异常,可以不用加try_x0002_catch语句捕获异常。9精品课程10精品课程【例10.3】对于运行时异常通常不采用抛出或捕获处理方式,而是应该提前预判,防止这种异常发生,做到未雨绸缪。例10.1中,在进行除法运算之前应该判断除数是非0的,修改为如下代码。//HelloWorld.java文件packagecom.a51work6;publicclassHelloWorld{publicstaticvoidmain(String[]args){inta=0;intresult=divide(5,a);System.out.printf("divide(%d,%d)=%d",5,a,result);}publicstaticintdivide(intnumber,intdivisor){//判断除数divisor非零,防止运行时异常if(divisor!=0){returnnumber/divisor;}return0;}}11精品课程从代码可见,提前预判处理要比通过try-catch捕获异常要友好得多。除了如图10-1所示的异常,还有很多异常,随着学习的深入本书还会介绍一些常用的异常,其他异常读者可以自己查询API文档学习。10.2捕获异常在现实生活中大家是如何对待领导交待的任务呢?通常分为两种情况:自己有能力解决的自己处理;自己没有能力解决的反馈给领导。实际上对待受检查异常也是如此。使用当前方法可以解决,则捕获异常进行处理;如无法解决,则抛给上层调用方法处理。如果上层调用方法还无法解决,则继续抛给其上一层调用方法,异常就是这样向上传递,直到有方法对其进行处理,如果所有的方法都不能处理该异常,那么JVM会终止程序的运行。10.2.1 try-catch语句捕获异常是通过try-catch语句实现的,最基本的try-catch语句语法格式如下:try{//可能会发生异常的语句}catch(Throwablee){//处理异常e}1.try代码块try代码块中应该包含执行过程中可能会发生异常的语句。一条语句是否有可能发生异常,这要看语句中调用的方法。例如,日期格式化类DateFormat的日期解析方法parse(),该方法的完整定义如下:publicDateparse(Stringsource)throwsParseException方法后面的throwsParseException说明,当调用parse()方法时有可能产生ParseException异常。2.catch代码块每个try代码块可以有一个或多个catch代码块,用于处理try代码块中可能发生的多种异常。catch(Throwablee)语句中的e是捕获异常对象,e必须是Throwable的子类,异常对象e的作用域在该catch代码块中。【例10.4】try-catch示例。代码如下://HelloWorld.java文件packagecom.a51work6;importjava.text.DateFormat;importjava.text.ParseException;importjava.text.SimpleDateFormat;importjava.util.Date;publicclassHelloWorld{publicstaticvoidmain(String[]args){Datedate=readDate();System.out.println("日期="+date);}//解析日期publicstaticDatereadDate(){①try{Stringstr="2018-8-18"//"201A-18-18"DateFormatdf=newSimpleDateFormat("yyyy-MM-dd");12精品课程命令说明快捷键重命名重命名所选择的
Java
元素Alt+Shift+R移动移动所选择的
Java
元素Alt+Shift+V抽取方法创建一个包含当前所选语句或表达式的新方法,并相关的引用Alt+Shift+M抽取局部变量创建为当前所选表达式指定的新变量,并将选择替换为对新变量的引用Alt+Shift+L命令说明快捷键重命名重命名所选择的
Java
元素Alt+Shift+R移动移动所选择的
Java
元素Alt+Shift+V抽取方法创建一个包含当前所选语句或表达式的新方法,并相关的引用Alt+Shift+M抽取局部变量创建为当前所选表达式指定的新变量,并将选择替换为对新变量的引用Alt+Shift+L命令说明快捷键重命名重命名所选择的
Java
元素Alt+Shift+R移动移动所选择的
Java
元素Alt+Shift+V抽取方法创建一个包含当前所选语句或表达式的新方法,并相关的引用Alt+Shift+M抽取局部变量创建为当前所选表达式指定的新变量,并将选择替换为对新变量的引用Alt+Shift+L命令说明快捷键重命名重命名所选择的
Java
元素Alt+Shift+R移动移动所选择的
Java
元素Alt+Shift+V抽取方法创建一个包含当前所选语句或表达式的新方法,并相关的引用Alt+Shift+M抽取局部变量创建为当前所选表达式指定的新变量,并将选择替换为对新变量的引用Alt+Shift+L//从字符串中解析日期Datedate=df.parse(str);②returndate;}catch(ParseExceptione){③System.out.println("处理ParseException…");e.printStackTrace();④}returnnull;}}上述代码第①行中定义了一个静态方法用来将字符串解析成日期,但并非所有的字符串都是有效的日期字符串,因此调用代码第②行的解析方法parse()有可能发生ParseException异常,ParseException是受检查异常,在本例中使用try-catch捕获。代码第③行的e就是ParseException对象。代码第④行的e.printStackTrace()是打印异常堆栈跟踪信息,本例中的"2018-8-18"字符串是有个有效的日期字符串,因此不会发生异常。如果将字符串改为无效的日期字符串,如"201A-18-18",则会打印信息。10.2.2 处理ParseException异常代码如下:java.text.ParseException:Unparseabledate:"201A-18-18"日期=nullatjava.text.DateFormat.parse(UnknownSource)atcom.a51work6.HelloWorld.readDate(HelloWorld.java:24)atcom.a51work6.HelloWorld.main(HelloWorld.java:13)14精品课程在捕获到异常之后,通过e.printStackTrace()语句打印异常堆栈跟踪信息,往往只是用于调试,给程序员提示信息。堆栈跟踪信息对用户其实是没有意义的。例10.4中如果出现异常很有可能是用户输入的日期无效,捕获到异常之后给用户弹出一个对话框,提示用户输入日期无效,请用户重新输入,用户重新输入后再重新调用上述方法,这才是捕获异常之后的正确处理方案。10.2.3 多个catch代码块如果try代码块中有很多语句会发生异常,而且发生的异常种类又很多,那么可以在try后面跟有多个catch代码块,其语法格式如下:try{//可能会发生异常的语句}catch(Throwablee){//处理异常e}catch(Throwablee){//处理异常e}catch(Throwablee){//处理异常e}在有多个catch代码的情况下,只要一个catch代码块捕获到一个异常,其他的catch代码块就不再进行匹配。【例10.5】多个catch代码块示例。代码如下://HelloWorld.java文件packagecom.a51work6;publicclassHelloWorld{publicstaticvoidmain(String[]args){Datedate=readDate();System.out.println("读取的日期="+date);}publicstaticDatereadDate(){FileInputStreamreadfile=null;InputStreamReaderir=null;BufferedReaderin=null;try{readfile=newFileInputStream("readme.txt");①ir=newInputStreamReader(readfile);in=newBufferedReader(ir);//读取文件中的一行数据Stringstr=in.readLine();②if(str==null){returnnull;}DateFormatdf=newSimpleDateFormat("yyyy-MM-dd");Datedate=df.parse(str);③returndate;}catch(FileNotFoundExceptione){④System.out.println("处理FileNotFoundException...");e.printStackTrace();}catch(IOExceptione){⑤System.out.println("处理IOException...");e.printStackTrace();}catch(ParseExceptione){⑥System.out.println("处理ParseException...");e.printStackTrace();}returnnull;}}上述代码通过JavaI/O流技术从文件readme.txt中读取字符串,然后解析成为日期。由于JavaI/O技术还没有介绍,读者先不要关注I/O技术的细节,只考虑调用这种方法会发生异常即可。在try代码块中第①行代码调用FileInputStream构造方法会发生FileNotFoundException异常。第②行代码调用BufferedReader输入流的readLine()方法会发生IOException异常。从图10-1中可知,FileNotFoundException异常是IOException异常的子类,应该先捕获FileNotFoundException,见代码第④行,后捕获IOException,见代码第⑤行。如果将FileNotFoundException和IOException捕获顺序交换,代码如下:try{//可能会发生异常的语句}catch(IOExceptione){//IOException异常处理}catch(FileNotFoundExceptione){//FileNotFoundException异常处理}那么永远不会进入第二个catch代码块,即FileNotFoundException异常处理永远不会被执行。由于上述代码第⑥行ParseException异常与IOException和FileNotFoundException异常没有父子关系,捕获ParseException异常的位置可以随意放置。10.2.4 try-catch语句嵌套【例10.6】Java提供的try-catch语句可以任意嵌套。示例代码如下://HelloWorld.java文件packagecom.a51work6;publicclassHelloWorld{publicstaticvoidmain(String[]args){Datedate=readDate();System.out.println("读取的日期="+date);}publicstaticDatereadDate(){FileInputStreamreadfile=null;InputStreamReaderir=null;BufferedReaderin=null;try{readfile=newFileInputStream("readme.txt");ir=newInputStreamReader(readfile);in=newBufferedReader(ir);try{①Stringstr=in.readLine();②if(str==null){returnnull;}DateFormatdf=newSimpleDateFormat("yyyy-MM-dd");Datedate=df.parse(str);③returndate;}catch(ParseExceptione){System.out.println("处理ParseException...");e.printStackTrace();}④}catch(FileNotFoundExceptione){⑤System.out.println("处理FileNotFoundException...");e.printStackTrace();}catch(IOExceptione){⑥System.out.println("处理IOException...");e.printStackTrace();}returnnull;}}上述代码第①~第④行是捕获ParseException异常的try-catch语句,这个try-catch语句就是嵌套在捕获IOException和FileNotFoundException异常的try-catch语句中。程序执行时,内层如果发生异常,首先由内层catch进行捕获,如果捕获不到,则由外层catch捕获。例如,代码第②行的readLine()方法可能发生IOException异常,该异常无法被内层catch捕获,最后被代码第⑥行的外层catch捕获。10.2.5 多重捕获多个catch代码块客观上提高了程序的健壮性,但是程序代码量也大大增加了。有些异常虽然种类不同,但捕获之后的处理是相同的。示例代码如下:try{//可能会发生异常的语句}catch(FileNotFoundExceptione){//调用方法methodA处理}catch(IOExceptione){//调用方法methodA处理}catch(ParseExceptione){//调用方法methodA处理}虽然是三个不同类型的异常,但要求捕获之后的处理都是调用methodA方法,是否可以把这些异常合并处理,Java7推出了多重捕获(multi-catch)技术,可以帮助解决此类问题。上述代码可以修改如下:try{//可能会发生异常的语句}catch(IOException|ParseExceptione){//调用方法methodA处理}在catch中,多重捕获异常用“|”运算符连接起来。10.3释放资源有时在try-catch语句中会占用一些非Java资源,如打开文件、网络连接、打开数据库连接和使用数据结果集等,这些资源并非Java资源,不能通过JVM的垃圾收集器回收,需要程序员释放。为了确保这些资源能够被释放,可以使用finally代码块或Java7之后提供的自动资源管理(AutomaticResourceManagement)技术。10.3.1 finally代码块try-catch语句后面还可以跟一个finally代码块,即try-catch-finally语句语法格式如下:try{//可能会生成异常语句}catch(Throwablee1){//处理异常e1}catch(Throwablee2){//处理异常e1}catch(ThrowableeN){//处理异常eN}finally{//释放资源}无论try正常结束,还是catch异常结束,都会执行finally代码块,如图10-2所示。
图10-2finally代码块流程【例10.6】finally代码块示例。代码如下://HelloWorld.java文件packagecom.a51work6;publicclassHelloWorld{publicstaticvoidmain(String[]args){Datedate=readDate();System.out.println("读取的日期="+date);}publicstaticDatereadDate(){FileInputStreamreadfile=null;InputStreamReaderir=null;BufferedReaderin=null;try{readfile=newFileInputStream("readme.txt");ir=newInputStreamReader(readfile);in=newBufferedReader(ir);//读取文件中的一行数据Stringstr=in.readLine();if(str==null){returnnull;}DateFormatdf=newSimpleDateFormat("yyyy-MM-dd");Datedate=df.parse(str);returndate;}catch(FileNotFoundExceptione){System.out.println("处理FileNotFoundException...");e.printStackTrace();}catch(IOExceptione){System.out.println("处理IOException...");e.printStackTrace();}catch(ParseExceptione){System.out.println("处理ParseException...");e.printStackTrace();}finally{①try{if(readfile!=null){readfile.close();②}}catch(IOExceptione){e.printStackTrace();}try{if(ir!=null){ir.close();③}}catch(IOExceptione){e.printStackTrace();}try{if(in!=null){in.close();④}}catch(IOExceptione){e.printStackTrace();}}⑤returnnull;}}上述代码第①行至第⑤行是finally语句,在这里通过关闭流释放资源,FileInputStream、InputStreamReader和BufferedReader是三个输入流,它们都需要关闭,见代码第②行和第④行通过流的close()关闭流,但是流的close()方法还有可能发生IOException异常,所以这里又针对每一个close()语句还需要进行捕获处理。需要注意的是,为了使代码简洁,可能有的人会将finally代码中的多个嵌套的try_x0002_catch语句合并,例如,将上述代码进行修改,即将三个可以发生异常的close()方法放到一个try-catch中。读者可以考虑一下这样处理是否稳妥?每一个close()方法对应关闭一个资源,如果第一个close()方法关闭时发生了异常,那么后面的两个也不会关闭,因此以下的程序代码是有缺陷的。try{...}catch(FileNotFoundExceptione){...}catch(IOExceptione){...}catch(ParseExceptione){...}finally{try{if(readfile!=null){readfile.close();}if(ir!=null){ir.close();}if(in!=null){in.close();}}catch(IOExceptione){e.printStackTrace();}}10.3.2 自动资源管理例10.6中使用finally代码块释放资源会导致程序代码量大大增加,一个finally代码块往往比正常执行的程序还要多。在Java7之后提供自动资源管理(AutomaticResourceManagement)技术,可以替代finally代码块,优化代码结构,提高程序的可读性。自动资源管理是在try语句上的扩展,其语法格式如下:try(声明或初始化资源语句){//可能会生成异常语句}catch(Throwablee1){//处理异常e1}catch(Throwablee2){//处理异常e2}catch(ThrowableeN){//处理异常eN}在try语句后面添加一对小括号“()”,其中是声明或初始化资源语句,如有多条语句,语句之间用分号“;”分隔。【例10.7】自动资源管理示例,代码如下://HelloWorld.java文件packagecom.a51work6;publicclassHelloWorld{publicstaticvoidmain(String[]args){Datedate=readDate();System.out.println("读取的日期="+date);}publicstaticDatereadDate(){//自动资源管理try(FileInputStreamreadfile=newFileInputStream("readme.txt");①InputStreamReaderir=newInputStreamReader(readfile);②BufferedReaderin=newBufferedReader(ir))③{//读取文件中的一行数据Stringstr=in.readLine();if(str==null){returnnull;}DateFormatdf=newSimpleDateFormat("yyyy-MM-dd");Datedate=df.parse(str);returndate;}catch(FileNotFoundExceptione){System.out.println("处理FileNotFoundException...");e.printStackTrace();}catch(IOExceptione){System.out.println("处理IOException...");e.printStackTrace();}catch(ParseExceptione){System.out.println("处理ParseException...");e.printStackTrace();}returnnull;}}上述代码第①行至第③行是声明/初始化三个输入流,三条语句放在try语句后面小括号中,语句之间用分号“;”分隔,这就是应用了自动资源管理技术,采用了自动资源管理后就不再需要finally代码块,即不需要自己close这些资源,释放过程交给了JVM。10.3.3 throws与声明方法抛出异常一个方法如果能够处理异常,则需要捕获并处理。但是如果方法没有能力处理该异常,捕获它也没有任何意义,则需要在方法后面声明抛出该异常,通知上层调用者该方法有可能发生异常。在方法后面声明抛出异常使用throws关键字,这里可以回顾一下成员方法,其语法格式如下:classclassName{[public|protected|private][static][final|abstract][native][synchronized]typemethodName([paramList])[throwsexceptionList]{//方法体}}其中,参数列表之后的[throwsexceptionList]语句是声明抛出异常。方法中可能抛出的异常(除了Error和RuntimeException及其子类外)都必须通过throws语句列出,多个异常之间采用逗号(,)分隔。需要注意的是,如果声明抛出的多个异常类之间有父子关系,可以只声明抛出父类。但如果没有父子关系,最好明确声明抛出每一个异常,因为上层调用者会根据这些异常信息进行相应的处理。假如一个方法中有可能抛出IOException和ParseException两个异常,那么是否可以同时声明抛出IOException和ParseException呢?还是只声明抛出Exception呢?因为Exception是IOException和ParseException的父类,只声明抛出Exception从语法上是允许的,但是声明抛出IOException和ParseException更好一些。【例10.8】在readDate()方法后声明抛出异常。示例代码如下://HelloWorld.java文件packagecom.a51work6;publicclassHelloWorld{publicstaticvoidmain(String[]args){①try{Datedate=readDate();②System.out.println("读取的日期="+date);}catch(IOExceptione){③System.out.println("处理IOException...");e.printStackTrace();}catch(ParseExceptione){④System.out.println("处理ParseException...");e.printStackTrace();}}publicstaticDatereadDate()throwsIOException,ParseException{⑤//自动资源管理FileInputStreamreadfile=newFileInputStream("readme.txt");⑥InputStreamReaderir=newInputStreamReader(readfile);BufferedReaderin=newBufferedReader(ir);//读取文件中的一行数据Stringstr=in.readLine();⑦if(str==null){returnnull;}DateFormatdf=newSimpleDateFormat("yyyy-MM-dd");Datedate=df.parse(str);⑧returndate;}}由于readDate()方法中的代码第⑥、⑦、⑧行都有可能引发异常,在readDate()方法内又没有捕获处理,所有需要在代码第⑤行方法后声明抛出异常,事实上有三个异常:FileNotFoundException、IOException和ParseException,由于FileNotFoundException属于IOException异常,所以只声明抛出IOException和ParseException即可。一旦在readDate()方法中声明抛出了异常,那么它的调用者main()方法也会面临同样的问题:要么捕获异常自己处理,要么将异常抛出给上层调用者。一旦发生异常,main()方法也选择抛出,那么程序运行就会终止。本例中main()方法是捕获异常进行处理,捕获异常过程前文已经介绍过了,这里就不再赘述。10.3.4 自定义异常类为了提高代码的可重用性,用户可以自行开发一些Java类库或框架,其中还可以编写一些异常类。实现自定义异常类需要继承Exception类或其子类,如果自定义运行时异常类则需继承RuntimeException类或其子类。【例10.9】实现自定义异常类。示例代码如
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026浙江省社会主义学院招聘专职教师3人参考考试试题附答案解析
- 2026年马鞍山市当涂县数媒文旅发展有限责任公司公开招聘劳务派遣制工作人员备考考试试题附答案解析
- 生产报销制度模板范本
- 电装生产车间管理制度
- 公司生产保密制度
- 选矿厂安全生产奖罚制度
- 屠宰车间生产管理制度
- 安全生产工作巡查制度
- 铝箔生产现场管理制度
- 艺术中心安全生产制度
- 2026届杭州高级中学高二上数学期末联考试题含解析
- 弃土场规范规章制度
- 2026年水下机器人勘探报告及未来五至十年深海资源报告
- 安徽省芜湖市鸠江区2024-2025学年高一上学期期末考试生物试卷
- 2025年对中国汽车行业深度变革的观察与思考报告
- 双重预防体系建设自评报告模板
- 福建省泉州市晋江市2024-2025学年八年级上学期1月期末考试英语试题(含答案无听力音频及原文)
- GB/T 22417-2008叉车货叉叉套和伸缩式货叉技术性能和强度要求
- GB/T 20145-2006灯和灯系统的光生物安全性
- GB/T 1.1-2009标准化工作导则 第1部分:标准的结构和编写
- 长兴中学提前招生试卷
评论
0/150
提交评论