《2022年异常及其处理知识点》由会员分享,可在线阅读,更多相关《2022年异常及其处理知识点(10页珍藏版)》请在金锄头文库上搜索。
1、学习必备欢迎下载一.异常处理概述1. 程序正常执行顺序:逐语句顺序执行. 2. 语句的正常完成和突然完成。3. 异常出现 .1 执行过程中出现错误时,系统会自动创建一个对象(称作异常对象,包含出错信息)并且抛出这个对象,2. 程序执行期间遇到无法继续执行的情况,程序员可以创建一个异常对象,然后使用throw 语句抛出这个异常对象。4. 异常处理过程. 1)终止程序的正常执行顺序,转去查找处理该异常的代码. 查找策略:首先在当前函数查找,没有找到则本方法结束,到调用该方法的方法中继续查找, 如果一直查找到main 方法也没有找到处理该异常的代码,打印堆栈踪迹后程序结束。2).处理异常 .如果在调
2、用链的某个方法中找到处理这个异常的代码,则恢复程序正常执行状态,执行这段代码以及之后的代码。二.与异常有关的语句1.throw expression语句;2.try-catch-finally 语句三.Throwable 类及其子类Throwable Error Exception RuntimeException 检查型异常 = Exception 及其子类 - RuntimeException 及其子类Throwable 类的构造函数和方法构造函数Throwable() Throwable(String message) 方法String getMessage() String getLo
3、calizedMessage() void printStackTrace() Throwable fillInStackTrace() 四. throws 子句 -方法定义的完整语法。1.语法 . 方法修饰符结果类型方法名(形参表)throws 子句方法体throws 子句的语法是throws 异常类型名1, , 异常类型名n 其中 throws 是 java 保留字,诸异常类型名是检查型异常的名字。2. 对方法体的限制. 方法体中抛出的任何检查型异常,无论是由throw 语句抛出的还是由于调用其它方法而发生的检查型异常,其类型都必须是throws 子句中列出的某个类型或其子类型。否则编译期
4、间出错。因此,编译器能够保证:通过编译的程序中的所有检查型异常都得到了处理。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 1 页,共 10 页学习必备欢迎下载3. 对方法重写的限制. 子类重写方法f,那么子类的f 不能抛出比基类f 更多的检查型异常。但是允许重写的f 抛出较少的检查型异常,甚至不抛出任何检查型异常。重写子类方法时,如果允许子类方法抛出比基类方法更多的异常,那么将破坏“通过编译的程序中的所有检查型异常都得到了处理”这一事实。异常及其处理.一.异常处理概述在运行过程中,应用程序可能遇到各种错误。例如,从一个已经关闭的流读数据;访问数组
5、时数组下标越界;使用空引用调用方法等。许多程序员不检查可能的错误,理由是如果每执行一个语句都检查是否出错,将使程序的结构混乱,难以理解。为了解决程序的正确性和程序结构的清晰性之间的矛盾,程序设计语言引入了异常及异常处理机制。下面是java 语言的异常处理机制的粗略过程: 1.程序运行时出错,抛出异常对象.当程序执行过程中出现错误(例如 0 做除数,数组下标越界等 )时,系统会自动创建一个对象(称作异常对象,包含出错信息)并且抛出这个对象,或者在程序执行期间遇到无法继续执行的情况(例如打开文件失败,连接数据库失败等),程序员可以创建一个异常对象,然后使用throw 语句抛出这个异常对象。2.终止
6、程序的正常执行顺序,转去查找处理该异常的代码.只要有异常对象E 被抛出 (无论是由系统抛出的还是由throw 语句抛出的 ),程序就立即停止正常的执行顺序,转去查找处理异常对象E 的代码。查找策略是首先在当前方法中查找,没有找到则本方法结束,到调用该方法的方法中继续查找,如果一直查找到main 方法也没有找到处理该异常的代码,打印堆栈踪迹后程序结束。3.处理异常 .如果在调用链的某个方法中找到处理这个异常的代码,则执行这段代码以及之后的代码。与异常处理有关的语句是throw 语句,try-catch-finally 语句和 Throwable 类及其子类。二. 与异常处理有关的语句1. thr
7、ow 语句语法: throw expression;这里 throw 是保留字, expression是一个表达式, 它的值一定是某个Throwable 类对象的引用。 throw 语句的功能是:计算表达式得到一个Throwable 对象的引用e,抛出 e使得系统进入异常处理状态,查找处理该类异常的catch子句。如果找到这样的catch子句,系统恢复到正常执行程序的状态,开始处理异常;如果一直找不到处理该类异常的catch 子句, 线程终止。例.看下面代码段/创建 Throwable 对象,系统并不进入异常处理状态Throwable e=new Throwable(); /其它代码,系统正常
8、执行这些代码if (B) throw e; /抛出异常,系统进入异常处理状态,查找处理e 的代码。else /系统仍旧处于正常执行程序的状态,执行这些代码。2. try-catch-finally 语句语法 1:精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 2 页,共 10 页学习必备欢迎下载try statements /称作 try 块catch(Exception 类型 1 e1)statements_1/称作 catch块catch(Exception 类型 n en)statements_n/称作 catch 块语法 2:try sta
9、tements /称作 try 块catch(Exception 类型 1 e1)statements_1/称作 catch块catch(Exception 类型 n en)statements_n/称作 catch 块finally statements/称作 finally 块这里 try, catch,finally 都是 java 语言的保留字。e1,e2,en 是标识符。要特别注意,诸catch 子句的异常类型应该子类型在前,父类型在后,否则编译出错。因为父类型的catch会拦截子类型的异常对象,使子类型的catch 永远也不会起作用,成为不可抵达的代码。有因原因 R 突然完成正常完
10、成没有因抛出 V 突然结束正常完成有 catch 捕获 V?执行 try 块try 块正常完成?try-catch 语句正常完成执行下一语句catch 块正常完成?try 语句因 R 突然完成try 语句因抛出V 突然完成try-catch 语句的语义给 catch 中的 e 赋值 V 执行捕获 V 的 catch 块精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 3 页,共 10 页学习必备欢迎下载例. 因原因 R 突然完成正常完成没有因原因 S突然完成正常有因抛出 V 突然完成正常完成有 catch 捕获 V?执行 try 块try 块正常完成
11、?try 语句正常完成执行下一语句给 catch 中的 e 赋值 V 执行捕获 V 的 catch 块try-catch-finally 语句的语义执行 finally 块try 语句因原因 S 突然完成。catch 块正常完成2 1 3 1 2 因原因 S突然完成正常try 语句因抛出 V 突然完成执行 finally 块正常完成?try 语句因原因S 突然完成。(忘记抛出V) 因原因 S突然完成正常try 语句因原因 R 突然完成执行 finally 块正常结束?try 语句因原因S 突然完成。(忘记原因R) 3 F 块正常完成?精选学习资料 - - - - - - - - - 名师归纳总
12、结 - - - - - - -第 4 页,共 10 页学习必备欢迎下载package test_try; class MyError extends Error /定义一个Error 的子类MyError () MyError (String s)super(s); public class test_try static void throw_Error() /定义方法,它抛出Error 或 Exception throw new MyError (zzzz); / throw new NullPointerException(); public static void main(Strin
13、g args) try throw_Error (); /调用抛出异常的方法 catch (NullPointerException e) /捕获并处理异常System.out.println(NullPointerException); catch (Exception e) /捕获并处理异常System.out.println(Exception); finally /finally 块System.out.println(Executing finally block.); 第一个 throw 语句起作用时,程序的输出。由于 MyError继承自 Error ,因此两个catch子句都不
14、能捕获这个异常。test_try.MyError: zzzz /异常没被捕获。调用uncaughtException()方法,输出堆栈踪迹。at test_try.test_try.throwError(test_try.java:8) at test_try.test_try.main(test_try.java:13) Executing finally block. /此输出表明finally 块一定执行。Exception in thread main 第二个 throw 语句起作用时程序的输出。这时异常得到处理,因此不会输出堆栈踪迹。processing NullPointerExc
15、eption Executing finally block. 三. 异常类Throwable精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 5 页,共 10 页学习必备欢迎下载是所有异常类的超类。它只有两个子类Error 和 Exception。Error 类及其子类表示程序具有严重的错误,例如 VirtualMachineError就是 Error 的一个子类。Exception 类表示程序的某种状态,该状态是应用程序希望捕获的。Exception 类有为数众多的子类,像IOException ,SQLException ,NoSuchFiel
16、dException,NoSuchMethodException RuntimeException 等等。其中 RuntimeException 是 Exception 的重要子类,它也有许多子类,像ArithmeticException ClassCastException NegativeArraySizeException NullPointerException IndexOutOfBoundsException 等等。检查型异常 .Exception 的子类,但不是RuntimeException 或其子类的所有异常类型统称 为 检 查 型 异 常 (checking excepti
17、on); 其 它 异 常 类 型 , 即Error及 其 子 类 型 和RuntimeException 及其子类型统称为非检查型异常(unchecking exception)。关于检查型异常这一名称的来源,见方法定义中的throws 子句。Throwable 类及其子类都是具体类,并且绝大多数类仅仅是名称不同,所具有的方法都是继承自Throwable 类。Throwable Error Exception RuntimeException NoSuchFieldException NoSuchMethodException SQLException IOException Arithmet
18、icException . 检查型异常异常类型层次NullPointerException VirtualMachineError 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 6 页,共 10 页学习必备欢迎下载Throwable 类public class Throwable extends Object implements Serializable Throwable 类是所有 errors 和 exceptions的超类。只有该类及其子类的对象可由Java Virtual Machine 或 throw 语句抛出。也只有该类及其子类可以
19、做catch子句的参数类型. Throwable 类的实例用于指出异常情况已经出现,并且包含异常情况的相关信息。通常 throwable 类有两个构造函数:一个无参数的构造函数,一个带一个String 型参数 msg的构造函数,参数msg给出异常情况的详细信息。Throwable 类的对象包含两类信息:1.关于异常情况的信息(一个串 )。2.异常情况出现时执行堆栈的状态。构造函数Throwable() 构造一个 Throwable 对象,具有空错误消息的。Throwable(String message) 构造一个 Throwable 对象,其错误消息是message 。方法String ge
20、tMessage() 返回当前 Throwable 对象的错误消息。String getLocalizedMessage() 创建 Throwable 类的更具专用色彩的描述信息。继承Throwable 类的子类应该重写该方法, Throwable 类的 getLocalizedMessage()与 getMessage()功能相同。void printStackTrace() 打印该Throwable 对象的错误信息,并打印执行堆栈信息到标准错误流。具体打印形式与实现有关。java.lang.NullPointerException 第一行是e.toString()方法的结果,以下是堆栈信息
21、at MyClass.M2(MyClass.java:9) 发生异常的语句所在方法名,文件名,行号at MyClass.M1(MyClass.java:6) 调用前一方法的方法名,文件名,行号at MyClass.main(MyClass.java:3) 以后同上这个例子由运行如下程序产生1 class MyClass 2public static void main(String argv) 3M1(null); 4 5 static void M1(int a) 6M2(a); 7 8 static void M2(int b) 9System.out.println(b0); 10 11
22、 Throwable fillInStackTrace() 把当前对象加入执行堆栈踪迹,返回当前对象作为值。常用于重新抛出异常。例. 1 package test_exception; 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 7 页,共 10 页学习必备欢迎下载2 public class test_exception 3 public static void main(String args) 4 5 f1(); 6 7 static void f1() 8 f2 (); 9 10 static void f2() 11 try 12 t
23、hrow new NullPointerException (aaaa); 13 14 catch(NullPointerException e) 15 16 e.printStackTrace(); 17 NullPointerException e1=(NullPointerException)e.fillInStackTrace(); 18 System.out.println(e=e1); 19 e.printStackTrace(); 20 throw (NullPointerException)e.fillInStackTrace(); java.lang.NullPointerE
24、xception: aaaa /由第 16 行的 printStackTrace() 打印at my_1.my_1_main.f2(test_exception.java:12) at my_1.my_1_main.f1(test_exception.java:8) at my_1.my_1_main.main(test_exception.java:5) java.lang.NullPointerException: aaaa /由第 19 行的 printStackTrace() 打印at my_1.my_1_main.f2(test_exception my_1_main.java:17
25、) at my_1.my_1_main.f1(test_exception my_1_main.java:8) at my_1.my_1_main.main(test_exception my_1_main.java:5) java.lang.NullPointerException: aaaa /由第 20 行的 throw 引起at my_1.my_1_main.f2(test_exception my_1_main.java:20) at my_1.my_1_main.f1(test_exception my_1_main.java:8) at my_1.my_1_main.main(t
26、est_exception my_1_main.java:5) true/由第 18 行输出,表明e.printStackTrace() 返回的就是e。Exception in thread main 四. throws 子句 -方法定义的完整语法以前介绍的方法定义的语法是方法修饰符结果类型方法名(形参表)方法体方法定义的完整语法是方法修饰符结果类型方法名(形参表)throws 子句方法体这里新增加的语法成分是throws 子句,它的语法是精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 8 页,共 10 页学习必备欢迎下载throws 异常类型名1
27、, , 异常类型名n 其中 throws 是 java 保留字,诸异常类型名是检查型异常的名字(可以填写非检查型异常名,但它不会起任何作用) 。对方法体的限制. 方法体中抛出的任何检查型异常,无论是由throw 语句抛出的还是由于调用其它方法而发生的检查型异常,其类型都必须是throws 子句中列出的某个类型或其子类型。否则编译期间出错。这意味着如果方法f 的 throws 子句是 throws E1,Em,那么如果 f 的方法体中有throw new E( “” )形式的语句,其中E 是检查型异常,那么E 是E1,Em 中的一个,或者是E1, ,Em 中某一个的子类。如果方法 f 调用方法g
28、,那么 g 的 throws 子句中的每个检查型异常都必须是E1, ,Em之一或者是某个Ek 的子类。否则要么方法f 处理这个异常,要么编译时出错。并不要求方法f 必须抛出throws 子句列出的所有异常,而是说f 只能抛出throws 子句列出的检查型异常。因此,编译器能够保证:通过编译的程序中的所有检查型异常都得到了处理。这就命名这类异常为“检查型异常”的原因。对方法重写的限制. 假设方法f() throws E1,Em是基类的一个方法。如果子类需要重写方法f,那么f 不能抛出比基类f 更多类型的检查型异常,它只能抛出Ek 或 Ek 的子类型的异常。但是允许重写的f 抛出较少的检查型异常,
29、甚至不抛出异常。重写子类方法时,如果允许子类方法抛出比基类方法更多的异常,那么将破坏“通过编译的程序中的所有检查型异常都得到了处理”这一事实。例.这个例子说明,一个方法抛出的检查型异常必须是出现在throws 子句中列出的异常。public class test_checkedexception void g() throws NoSuchMethodException,NoSuchFieldException /抛出两种检查型异常 void f () throws NoSuchMethodException throw new NoSuchFieldException(); /编译出错, t
30、hrow 语句抛出的检查型异常/不在 throws 子句中g(); /编译出错,方法调用g()抛出的检查型异常不在throws 子句中 void f1( ) throws NoSuchMethodException /虽然 throw 语句抛出了throws 子句之外的检查型异常,但f1 处理了该异常,正确。try throw new NoSuchFieldException(); catch(NoSuchFieldException e) 精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 9 页,共 10 页学习必备欢迎下载void f2( ) t
31、hrows NoSuchMethodException /虽然 g()抛出了 throws 子句之外的检查型异常,但f2 处理了该异常,正确。try g(); catch(NoSuchFieldException e) 下面的例子说明,重写的方法不能抛出更多的异常,但可以抛出较少的异常,甚至不抛出异常。class test_inherit extends test_checkedexception void f1() throws NoSuchMethodException,NoSuchFieldException /编译出错 .重写的 f1 比基类的f1 抛出更多的检查型异常。 void f2() /编译通过 .允许重写的方法比基类方法抛出更少的检查型异常,/甚至不抛出检查型异常。 习题 . 1.重写子类方法时,如果允许子类方法抛出比基类方法更多的异常,那么将破坏“通过编译的程序中的所有检查型异常都得到了处理”这一事实。为什么?提示:方法 g 调用方法f,方法 f 至少有本类和基类两个版本。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 10 页,共 10 页