8异常及其处理知识点文档格式.docx

上传人:b****1 文档编号:432384 上传时间:2023-04-28 格式:DOCX 页数:16 大小:126.84KB
下载 相关 举报
8异常及其处理知识点文档格式.docx_第1页
第1页 / 共16页
8异常及其处理知识点文档格式.docx_第2页
第2页 / 共16页
8异常及其处理知识点文档格式.docx_第3页
第3页 / 共16页
8异常及其处理知识点文档格式.docx_第4页
第4页 / 共16页
8异常及其处理知识点文档格式.docx_第5页
第5页 / 共16页
8异常及其处理知识点文档格式.docx_第6页
第6页 / 共16页
8异常及其处理知识点文档格式.docx_第7页
第7页 / 共16页
8异常及其处理知识点文档格式.docx_第8页
第8页 / 共16页
8异常及其处理知识点文档格式.docx_第9页
第9页 / 共16页
8异常及其处理知识点文档格式.docx_第10页
第10页 / 共16页
8异常及其处理知识点文档格式.docx_第11页
第11页 / 共16页
8异常及其处理知识点文档格式.docx_第12页
第12页 / 共16页
8异常及其处理知识点文档格式.docx_第13页
第13页 / 共16页
8异常及其处理知识点文档格式.docx_第14页
第14页 / 共16页
8异常及其处理知识点文档格式.docx_第15页
第15页 / 共16页
8异常及其处理知识点文档格式.docx_第16页
第16页 / 共16页
亲,该文档总共16页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

8异常及其处理知识点文档格式.docx

《8异常及其处理知识点文档格式.docx》由会员分享,可在线阅读,更多相关《8异常及其处理知识点文档格式.docx(16页珍藏版)》请在冰点文库上搜索。

8异常及其处理知识点文档格式.docx

StringgetLocalizedMessage()

voidprintStackTrace()

ThrowablefillInStackTrace()

四.throws子句---方法定义的完整语法。

1.语法.

方法修饰符结果类型方法名(形参表)throws子句方法体

throws子句的语法是

throws异常类型名1,……,异常类型名n

其中throws是java保留字,诸异常类型名是检查型异常的名字。

2.对方法体的限制.

方法体中抛出的任何检查型异常,无论是由throw语句抛出的还是由于调用其它方法而发生的检查型异常,其类型都必须是throws子句中列出的某个类型或其子类型。

否则编译期间出错。

因此,编译器能够保证:

通过编译的程序中的所有检查型异常都得到了处理。

3.对方法重写的限制.

子类重写方法f,那么子类的f不能抛出比基类f更多的检查型异常。

但是允许重写的f抛出较少的检查型异常,甚至不抛出任何检查型异常。

重写子类方法时,如果允许子类方法抛出比基类方法更多的异常,那么将破坏“通过编译的程序中的所有检查型异常都得到了处理”这一事实。

 

异常及其处理.

在运行过程中,应用程序可能遇到各种错误。

例如,从一个已经关闭的流读数据;

访问数组时数组下标越界;

使用空引用调用方法等。

许多程序员不检查可能的错误,理由是如果每执行一个语句都检查是否出错,将使程序的结构混乱,难以理解。

为了解决程序的正确性和程序结构的清晰性之间的矛盾,程序设计语言引入了异常及异常处理机制。

下面是java语言的异常处理机制的粗略过程:

1.程序运行时出错,抛出异常对象.当程序执行过程中出现错误(例如0做除数,数组下标越界等)时,系统会自动创建一个对象(称作异常对象,包含出错信息)并且抛出这个对象,或者在程序执行期间遇到无法继续执行的情况(例如打开文件失败,连接数据库失败等),程序员可以创建一个异常对象,然后使用throw语句抛出这个异常对象。

2.终止程序的正常执行顺序,转去查找处理该异常的代码.只要有异常对象E被抛出(无论是由系统抛出的还是由throw语句抛出的),程序就立即停止正常的执行顺序,转去查找处理异常对象E的代码。

查找策略是首先在当前方法中查找,没有找到则本方法结束,到调用该方法的方法中继续查找,如果一直查找到main方法也没有找到处理该异常的代码,打印堆栈踪迹后程序结束。

3.处理异常.如果在调用链的某个方法中找到处理这个异常的代码,则执行这段代码以及之后的代码。

与异常处理有关的语句是throw语句,try-catch-finally语句和Throwable类及其子类。

二.与异常处理有关的语句

1.throw语句

语法:

throwexpression;

这里throw是保留字,expression是一个表达式,它的值一定是某个Throwable类对象的引用。

throw语句的功能是:

计算表达式得到一个Throwable对象的引用e,抛出e使得系统进入异常处理状态,查找处理该类异常的catch子句。

如果找到这样的catch子句,系统恢复到正常执行程序的状态,开始处理异常;

如果一直找不到处理该类异常的catch子句,线程终止。

例.看下面代码段

//创建Throwable对象,系统并不进入异常处理状态

Throwablee=newThrowable();

……//其它代码,系统正常执行这些代码

if(B)throwe;

//抛出异常,系统进入异常处理状态,查找处理e的代码。

else

……//系统仍旧处于正常执行程序的状态,执行这些代码。

2.try-catch-finally语句

语法1:

try

{statements}//{…}称作try块

catch(Exception类型1e1){statements_1}//{…}称作catch块

……

catch(Exception类型nen){statements_n}//{…}称作catch块

语法2:

catch(Exception类型nen){statements_n}//{…}称作catch块

finally{statements}//{…}称作finally块

这里try,catch,finally都是java语言的保留字。

e1,e2,…,en是标识符。

要特别注意,诸catch子句的异常类型应该子类型在前,父类型在后,否则编译出错。

因为父类型的catch会拦截子类型的异常对象,使子类型的catch永远也不会起作用,成为不可抵达的代码。

例.

packagetest_try;

classMyErrorextendsError

{//定义一个Error的子类

MyError(){}

MyError(Strings){super(s);

}

publicclasstest_try

{

staticvoidthrow_Error()

{

//定义方法,它抛出Error或Exception

thrownewMyError("

zzzz"

);

//thrownewNullPointerException();

}

publicstaticvoidmain(String[]args)

{

try{

throw_Error();

//调用抛出异常的方法

catch(NullPointerExceptione)

{//捕获并处理异常

System.out.println("

NullPointerException"

catch(Exceptione)

System.out.println("

Exception"

finally{//finally块

Executingfinallyblock."

第一个throw语句起作用时,程序的输出。

由于MyError继承自Error,因此两个catch子句都不能捕获这个异常。

test_try.MyError:

zzzz//异常没被捕获。

调用uncaughtException()方法,输出堆栈踪迹。

attest_try.test_try.throwError(test_try.java:

8)

attest_try.test_try.main(test_try.java:

13)

Executingfinallyblock.//此输出表明finally块一定执行。

Exceptioninthread"

main"

第二个throw语句起作用时程序的输出。

这时异常得到处理,因此不会输出堆栈踪迹。

processingNullPointerException

Executingfinallyblock.

三.异常类

Throwable

是所有异常类的超类。

它只有两个子类Error和Exception。

Error类

及其子类表示程序具有严重的错误,例如VirtualMachineError就是Error的一个子类。

Exception类

表示程序的某种状态,该状态是应用程序希望捕获的。

Exception类有为数众多的子类,像

IOException,

SQLException,

NoSuchFieldException,

NoSuchMethodException

RuntimeException

等等。

其中RuntimeException是Exception的重要子类,它也有许多子类,像

ArithmeticException

ClassCastException

NegativeArraySizeException

NullPointerException

IndexOutOfBoundsException

检查型异常.Exception的子类,但不是RuntimeException或其子类的所有异常类型统称为检查型异常(checkingexception);

其它异常类型,即Error及其子类型和RuntimeException及其子类型统称为非检查型异常(uncheckingexception)。

关于检查型异常这一名称的来源,见方法定义中的throws子句。

Throwable类及其子类都是具体类,并且绝大多数类仅仅是名称不同,所具有的方法都是继承自Throwable类。

Throwable类

publicclassThrowableextendsObjectimplementsSerializable

Throwable类是所有errors和exceptions的超类。

只有该类及其子类的对象可由JavaVirtualMachine或throw语句抛出。

也只有该类及其子类可以做catch子句的参数类型.

Throwable类的实例用于指出异常情况已经出现,并且包含异常情况的相关信息。

通常throwable类有两个构造函数:

一个无参数的构造函数,一个带一个String型参数msg的构造函数,参数msg给出异常情况的详细信息。

Throwable类的对象包含两类信息:

1.关于异常情况的信息(一个串)。

2.异常情况出现时执行堆栈的状态。

构造一个Throwable对象,具有空错误消息的。

构造一个Throwable对象,其错误消息是message。

返回当前Throwable对象的错误消息。

创建Throwable类的更具专用色彩的描述信息。

继承Throwable类的子类应该重写该方法,Throwable类的getLocalizedMessage()与getMessage()功能相同。

打印该Throwable对象的错误信息,并打印执行堆栈信息到标准错误流。

具体打印形式与实现有关。

java.lang.NullPointerException第一行是e.toString()方法的结果,以下是堆栈信息

atMyClass.M2(MyClass.java:

9)发生异常的语句所在方法名,文件名,行号

atMyClass.M1(MyClass.java:

6)调用前一方法的方法名,文件名,行号

atMyClass.main(MyClass.java:

3)以后同上

这个例子由运行如下程序产生

1.classMyClass{

2.publicstaticvoidmain(String[]argv){

3.M1(null);

4.}

5.staticvoidM1(int[]a){

6.M2(a);

7.}

8.staticvoidM2(int[]b){

9.System.out.println(b[0]);

10.}

11.}

把当前对象加入执行堆栈踪迹,返回当前对象作为值。

常用于重新抛出异常。

1packagetest_exception;

2publicclasstest_exception{

3publicstaticvoidmain(String[]args)

4{

5f1();

6}

7staticvoidf1(){

8f2();

9}

10staticvoidf2(){

11try{

12thrownewNullPointerException("

aaaa"

13}

14catch(NullPointerExceptione)

15{

16e.printStackTrace();

17NullPointerException

e1=(NullPointerException)e.fillInStackTrace();

18System.out.println(e==e1);

19e.printStackTrace();

20throw(NullPointerException)e.fillInStackTrace();

java.lang.NullPointerException:

aaaa//由第16行的printStackTrace()打印

atmy_1.my_1_main.f2(test_exception.java:

12)

atmy_1.my_1_main.f1(test_exception.java:

atmy_1.my_1_main.main(test_exception.java:

5)

aaaa//由第19行的printStackTrace()打印

atmy_1.my_1_main.f2(test_exceptionmy_1_main.java:

17)

atmy_1.my_1_main.f1(test_exceptionmy_1_main.java:

atmy_1.my_1_main.main(test_exceptionmy_1_main.java:

aaaa//由第20行的throw引起

20)

true//由第18行输出,表明e.printStackTrace()返回的就是e。

四.throws子句---方法定义的完整语法

以前介绍的方法定义的语法是

方法修饰符结果类型方法名(形参表)方法体

方法定义的完整语法是

这里新增加的语法成分是throws子句,它的语法是

throws异常类型名1,……,异常类型名n

其中throws是java保留字,诸异常类型名是检查型异常的名字(可以填写非检查型异常名,但它不会起任何作用)。

对方法体的限制.

这意味着如果方法f的throws子句是throwsE1,…,Em,那么

如果f的方法体中有thrownewE(“…”)形式的语句,其中E是检查型异常,那么E是E1,…,Em中的一个,或者是E1,…,Em中某一个的子类。

如果方法f调用方法g,那么g的throws子句中的每个检查型异常都必须是E1,…,Em之一或者是某个Ek的子类。

否则要么方法f处理这个异常,要么编译时出错。

并不要求方法f必须抛出throws子句列出的所有异常,而是说f只能抛出throws子句列出的检查型异常。

这就命名这类异常为“检查型异常”的原因。

对方法重写的限制.

假设方法f()throwsE1,…,Em{…}是基类的一个方法。

如果子类需要重写方法f,那么f不能抛出比基类f更多类型的检查型异常,它只能抛出Ek或Ek的子类型的异常。

但是允许重写的f抛出较少的检查型异常,甚至不抛出异常。

例.这个例子说明,一个方法抛出的检查型异常必须是出现在throws子句中列出的异常。

publicclasstest_checkedexception

voidg()throwsNoSuchMethodException,NoSuchFieldException

……//抛出两种检查型异常

voidf()throwsNoSuchMethodException

{

thrownewNoSuchFieldException();

//编译出错,throw语句抛出的检查型异常

//不在throws子句中

g();

//编译出错,方法调用g()抛出的检查型异常不在throws子句中

voidf1()throwsNoSuchMethodException

{//虽然throw语句抛出了throws子句之外的检查型异常,但f1处理了该异常,正确。

try

catch(NoSuchFieldExceptione){}

voidf2()throwsNoSuchMethodException

{//虽然g()抛出了throws子句之外的检查型异常,但f2处理了该异常,正确。

{

下面的例子说明,重写的方法不能抛出更多的异常,但可以抛出较少的异常,甚至不抛出异常。

classtest_inheritextendstest_checkedexception

voidf1()throwsNoSuchMethodException,NoSuchFieldException

//编译出错.重写的f1比基类的f1抛出更多的检查型异常。

voidf2()

//编译通过.允许重写的方法比基类方法抛出更少的检查型异常,

//甚至不抛出检查型异常。

习题.

1.重写子类方法时,如果允许子类方法抛出比基类方法更多的异常,那么将破坏“通过编译的程序中的所有检查型异常都得到了处理”这一事实。

为什么?

提示:

方法g调用方法f,方法f至少有本类和基类两个版本。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2