Java中自定义异常精Word文件下载.docx
- 文档编号:16232117
- 上传时间:2022-11-21
- 格式:DOCX
- 页数:7
- 大小:19.24KB
Java中自定义异常精Word文件下载.docx
《Java中自定义异常精Word文件下载.docx》由会员分享,可在线阅读,更多相关《Java中自定义异常精Word文件下载.docx(7页珍藏版)》请在冰豆网上搜索。
publicclassTrans
{
publicstaticvoidmain(String[]args
try
BufferedReaderrd=null;
Writerwr=null;
FilesrcFile=newFile((args[0];
FiledstFile=newFile((args[1];
rd=newBufferedReader(newInputStreamReader(new
FileInputStream(srcFile,args[2];
wr=newOutputStreamWriter(newFileOutputStream(dstFile,args[3];
//注意下面这条语句,它有什么问题吗?
if(rd==null||wr==nullthrownewException("
error!
test!
"
;
while(true
StringsLine=rd.readLine(;
if(sLine==nullbreak;
wr.write(sLine;
wr.write("
\r\n"
}
finally
wr.flush(;
wr.close(;
rd.close(;
catch(IOExceptionex
ex.printStackTrace(;
熟悉java语言的程序员朋友们,你们认为上面的程序有什么问题吗?
编译能通过吗?
如果不能,那么原因又是为何呢?
好了,有了自己的分析和预期之后,不妨亲自动手编译一下上面的小程序,呵呵!
结果确实如您所料?
是的,的确是编译时报错了,错误信息如下:
E:
\Trans.java:
20:
unreportedexceptionjava.lang.Exception;
mustbecaughtordeclaredtobethrown
1error
上面这种编译错误信息,相信Java程序员肯定见过(可能还是屡见不鲜!
!
相信老练一些的Java程序员一定非常清楚上述编译出错的原因。
那就是如错误信息中(“mustbecaught”描述的那样,在Java的异常处理模型中,要求所有被抛出的异常都必须要有对应的“异常处理模块”。
也即是说,如果你在程序中throw出一个异常,那么在你的程序中(函数中就必须要catch这个异常(处理这个异常。
例如上面的例子中,你在第20行代码处,抛出了一个Exception类型的异常,但是在该函数中,却没有catch并处理掉此异常的地方。
因此,这样的程序即便是能够编译通过,那么运行时也是致命的(可能导致程序的崩溃,所以,Java语言干脆在编译时就尽可能地检查(并卡住这种本不应该出现的错误,这无疑对提高程序的可靠性大有帮助。
但是,在Java语言中,这就是必须的。
如果一个函数中,它运行时可能会向上层调用者函数抛出一个异常,那么,它就必须在该函数的声明中显式的注明(采用throws关键字。
还记得刚才那条编译错误信息吗?
“mustbecaughtordeclaredtobethrown”,其中“mustbecaught”上面已经解释了,而后半部分呢?
“declaredtobethrown”是指何意呢?
其实指的就是“必须显式地声明某个函数可能会向外部抛出一个异常”,也即是说,如果一个函数内部,它可能抛出了一种类型的异常,但该函数内部并不想(或不宜catch并处理这种类型的异常,此时,它就必须使用throws关键字来声明该函数可能会向外
部抛出一个异常,以便于该函数的调用者知晓并能够及时处理这种类型的异常。
下面列出了这几种情况的比较,代码如下:
//示例程序1,这种写法能够编译通过
packagecom.ginger.exception;
publicclassTrans{
publicstaticvoidmain(String[]args{
try{
test(;
}catch(Exceptionex{
staticvoidtest({
thrownewException("
ToshowExceptionSuccessed"
//示例程序2,这种写法就不能够编译通过
//虽然这里能够捕获到Exception类型的异常
catch(Exceptionex{
test"
//示例程序3,这种写法又能够被编译通过
catch(Exceptionex
//由于函数声明了可能抛出Exception类型的异常
staticvoidtest(throwsException
//示例程序4,它又不能够被编译通过了
//虽然test(函数并没有真正抛出一个Exception类型的异常
//但是由于它函数声明时,表示它可能抛出一个Exception类型的异常//所以,这里仍然不能被编译通过。
//呵呵!
体会到了Java异常处理模型的严谨吧!
不知上面几个有联系的示例是否能够给大家带来“豁然开朗”的感觉,坦率的说,Java提供的异常处理模型并不复杂,相信太多太多Java程序员有着比我更深刻的认识。
最后,补充一种例外情况,请看如下代码:
staticvoidtest(throwsError{
thrownewError("
故意抛出一个Error"
朋友们!
上面的程序能被编译通过吗?
注意,按照刚才上面所总结出的规律:
在Java的异常处理模型中,要求所有被抛出的异常都必须要有对应的catch块!
那么上面的程序肯定不能被编译通过,因为Error和Exception都是从Throwable直接派生而来,而test函数声明了它可能抛出Error类型的异常,但在main函数中却并没有catch(Error或catch(Throwable块,所以它理当是会编译出错的!
真的吗?
不妨试试!
呵呵!
结果并非我们之预料,而它恰恰是正确编译通过了。
为何?
WHY?
其实,原因很简单,那就是因为Error异常的特殊性。
Java异常处理模型中规定:
Error和从它派生而来的所有异常,都表示系统中出现了一个非常严重的异常错误,并且这个错误可能是应用程序所不能恢复的(其实这在前面的内容中已提到过。
因此,如果系统中真的出现了一个Error类型的异常,那么则表明,系统已处于崩溃不可恢复的状态中,此时,作为编写Java应用程序的你,已经是没有必要(也没能力来处理此等异常错误。
所以,javac编译器就没有必要来保证:
“在编译时,所有的Error异常都有其对应的错误处理模块”。
当然,Error类型的异常一般都是由系统遇到致命的错误时所抛出的,它最后也由Java虚拟机所处理。
而作为Java程序员的你,可能永远也不会考虑抛出一个Error类型的异常。
因此Error是一个特例情况!
特别关注一下RuntimeException
上面刚刚讨论了一下Error类型的异常处理情况,Java程序员一般无须关注它(处理这种异常。
另外,其实在Exception类型的异常对象中,也存在一种比较特别的“异常”类型,那就是RuntimeException,虽然它是直接从Exception派生而来,但是Java编译器(javac对RuntimeException却
是特殊待遇,而且是照顾有加。
不信,看看下面的两个示例吧!
代码如下:
//示例程序1//它不能编译通过,我们可以理解importjava.io.*;
publicclassTrans{publicstaticvoidmain(String[]args{test(;
}staticvoidtest({//注意这条语句thrownewException("
故意抛出一个Exception"
}}//示例程序2//可它却为什么能够编译通过呢?
importjava.io.*;
}staticvoidtest({//注意这条语句thrownewRuntimeException("
故意抛出一个RuntimeException"
}}对上面两个相当类似的程序,javac编译时却遭遇了两种截然不同的处理,按理说,2个示例程序也应该像第1个示例程序那样,第编译时报错!
但是javac编译它时,却例外地让它通过它,而且在运行时,java虚拟机也捕获到了这个异常,并且会在console打印出详细的异常信息。
运行结果如下:
java.lang.RuntimeException:
故意抛出一个RuntimeExceptionatTrans.test(Trans.java:
13atTrans.main(Trans.java:
8Exceptioninthread"
main"
为什么对于RuntimeException类型的异常(以及从它派生而出的异常类型),
javac和java虚拟机都特殊处理呢?
要知道,这可是与“Java异常处理模型更严谨和更安全”的设计原则相抵触的呀!
究竟是为何呢?
这简直让人不法理解呀!
只不过,Java语言中,RuntimeException被统一纳入到了Java语言和JDK的规范之中。
请看如下代码,来验证一下我们的理解!
}staticvoidtest({inti=4;
intj=0;
//运行时,这里将触发了一个ArithmeticException//ArithmeticException从RuntimeException派生而来System.out.println("
i/j="
+i/j;
}}运行结果如下:
java.lang.ArithmeticException:
/byzeroatTrans.test(Trans.java:
16atTrans.main(Trans.java:
又如下面的例子,也会产生一个RuntimeException,代码如下:
}staticvoidtest({Stringstr=null;
//运行时,这里将触发了一个NullPointerException
//NullPointerException从RuntimeException派生而来pareTo("
abc"
}}所以,针对RuntimeException类型的异常,javac是无法通过编译时的静态语法检测来判断到底哪些函数(或哪些区域的代码)可能抛出这类异常(这完全取决于运行时状态,或者说运行态所决定的),也正因为如此,Java异常处理模型中的“mustbecaughtordeclaredtobethrown”规则也不适用于RuntimeException(所以才有前面所提到过的奇怪编译现象,这也属于特殊规则吧)。
但是,Java虚拟机却需要有效地捕获并处理此类异常。
当然,RuntimeException也可以被程序员显式地抛出,而且为了程序的可靠性,对一些可能出现“运行时异常(RuntimeException)”的代码区域,程序员最好能够及时地处理这些意外的异常,也即通过catch(RuntimeExcetion或catch(Exception来捕获它们。
如下面的示例程序,代码如下:
publicclassTrans{publicstaticvoidmain(String[]args{try{test(;
}//在上层的调用函数中,最好捕获所有的Exception异常!
catch(Exceptione{System.out.println("
gohere!
e.printStackTrace(;
}}//这里最好显式地声明一下,表明该函数可能抛出RuntimeExceptionstaticvoidtest(throwsRuntimeException{Stringstr=null;
//运行时,这里将触发了一个NullPointerException//NullPointerException从RuntimeException派生而来pareTo("
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java 自定义 异常