异常
- 程序在运行过程中出现的非正常的情况
- 预先准备一段程序代码,当程序中出现异常时,让其执行预先准备的代码
- 异常处理可以减少因程序出现异常而给用户带来的损失和不必要的麻烦
- 异常的父类—>Throwable—>位于java.lang包中
- 构造方法
- Throwable():无参数的构造方法
- Throwable(String message):带有字符串类型的异常信息构造方法
- 成员方法
- String getMessage():以字符串类型获取异常信息 —> 获取有参构造方法的String —> 给用户做提示应用
- void printStackTrace():打印输出因异常而产生的堆栈追踪的异常信息 —> 给开发人员调试或是查看异常信息时应用
- 构造方法
异常分类
-
Error—>Throwable的直接子类—>错误
- 程序中严重的错误—>如内存不足或是因方法调用而产生栈溢出等
- 无法处理或修改源代码—>无穷递归java.lang.StackOverflowError(栈溢出)
-
Exception—>Throwable的直接子类—>异常
-
RuntimeException —> Exception的直接子类 —> 运行时异常、为检查异常
- RuntimeException的直接或间接子类的异常都被称为运行时异常
- 在编译阶段,编译器不会检测此类异常 —> 在运行时报错
- 运行时可以处理也可以不处理,可以通过代码规范将此类异常避免
- 常见异常
- java.lang.ClassCastException类型转换异常
- java.lang.NullPointerException空指针异常
- java.lang.ArrayIndexOutOfBoundsException数组下标越界异常
- java.lang.StringIndexOutOfBoundsException字符串下标越界异常
- java.lang.IndexOutOfBoundsException下标越界异常—>集合直接报下标越界
- java.lang.NumberFormatException数值格式转换异常
-
非RuntimeException —> 非运行时异常、已检查异常 —> 区分语法错误
- 和RuntimeException没有任何继承关系的异常类
- 在编译阶段被编译器检测,在编译时报错
- 非运行时异常出现时必须处理,否则程序无法运行
- Class.forName(“hang”); 非运行时异常
-
-
异常产生原因
- 自动产生异常—>程序在运行过程中遇到错误的代码,自动产生异常,程序因异常而被终止
- 手动产生异常—>throw
- throw new 异常类类名 ( " 异常信息 " ) ; —> 定义在方法等内部—>类似于return,结束当前程序
-
异常的传递
- 程序运行过程中遇到异常,异常沿着方法的调用链进行反方向传递,直到传递给JVM,最终程序因异常而被终止
- 查看控制台异常报错信息时,从上往下看第一个,若第一个是程序没有的行标,则看第二个,依此类推
异常处理
-
消极异常处理 —> 也称为声明异常
- 关键字throws—>定义在方法声明位置—>修饰符 返回值类型 方法名 ( 形参列表 ) throws 异常类名1,异常类名2,…{ } ----> 一个方法可以消极处理多个异常
- 消极处理异常时,利用多态技术可以借助父类型异常来处理其子类型异常
- 消极处理异常只是一种推卸责任,异常没有彻底解决,只是抛给方法的调用者,程序依然会因异常而被终止。
- 消极处理异常可以使非运行时异常在编译阶段编译通过。
-
积极异常处理 —> 也称为捕获异常
try{ //try后面可以跟多个catch //可能出现异常的语句 } catch(异常类名 e) { //当异常出现时执行的语句 } finally { //不管有没有异常必须执行的语句,实际开发时,一般finally里不定义return,通常将关闭资源的语句定义在finally中 ---> 如IO流,数据库连接资源等 } //try中出现异常时,会从上往下依次匹配catch,直到匹配成功,执行对应catch语句 //利用多态可以通过父类型处理其子类型的异常,但是定义子类的catch块要在父类前 //catch只能定义在try中可能出现的非运行时异常,catch可以定义任意的运行时异常,不管try是否能出现此类异常 finally ---> 结合积极异常来使用 --->可以结合程序需求是否写finally 结构小结 try {} catch(){} try {} catch(){}catch(){} try {} catch(){}finally{} try {} catch(){}catch(){}finally{} try {} finally{} //为了让一些语句必须执行到 try { try {}catch(){} }catch(){} try {} catch(){ try{}catch(){} } try {} catch(){} finally{ try{}catch(){} } //try后面要么跟catch,要么跟finally,不能单独存在 //try后面可以跟多个catch,但是只能跟一个finally,而且catch在前,finally在后
public static void main(String[] args){ int r = m1(); System.out.println("r = " + r); //m = 3;return有自己的空间 } public static int m1() { int m = 3; try { return m; } catch (Exception e) { return -1; } finally{ m = 7; } }
自定义异常类
-
定义一个类继承Exception或是其子类,为非运行时异常
-
继承RuntimeException或其子类为运行时异常
-
通常提供两个构造方法,一个无参,一个String类型的有参的,然后用super()给父类
-
方法的覆盖
- 子类的方法名、返回值类型、形参列表和父类相同
- 子类访问修饰符和父类相同或更宽
- 子类不能抛出比父类更宽的异常
-
方法重载对异常没有要求
throw | throws | |
---|---|---|
位置 | 应用在方法内部,用于手动产生异常 | 应用在方法声明部分,用于消极处理异常 |
final | finalize | finally |
---|---|---|
关键字,用于修饰类、方法、变量 final修饰的类不能被继承,没有子类,如String Math System等 | 方法名,垃圾回收器在回收垃圾对象时,JVM自动调用的方法 | 关键字,用于积极处理异常,配合try catch,finally中语句不管有没有异常,都会执行 |