一、概述
- 什么是异常?程序执行过程中的不正常情况
- 异常的作用?增强程序的健壮性
异常在Java中以类的形式存在,每一个异常类都可以创建异常对象
二、继承结构

所有异常都是发生在运行阶段的,编译时异常之所以叫做编译时异常,是因为该种异常必须在编译时进行处理
三、处理方式
3.1 上抛throws
在方法声明位置使用throws关键字抛出,谁调用我这个方法,我就抛给谁(抛给调用者来处理)
- 一般不建议在main方法上使用该方式,因为这个异常将会抛给虚拟机,JVM最终只能终止程序
相关:throw new xxxException();(手动抛异常)
3.2 捕捉try…catch
使用try…catch语句进行捕捉处理
- catch后面的小括号中的类型可以是具体的异常类型,也可以是该异常类型的父类型
- catch可以写多个。建议catch的时候,精确地一个个处理,有利于程序调试,并且从上到下catch到的异常类型大小必须是从小到大
- finally
- finally子句中的代码是最后一定会执行的!!!除非直接结束当前正在运行中的JVM:System.exit(0);
- 通常在finally中完成对资源的释放/关闭
一道面试题
public class ExceptionTest {public static void main(String[] args) {int result = m();System.out.println(result); // 100}/*** 这里返回的值是100* @return* 两条规则:* 1、方法体中的代码必须遵循自上而下顺序依次逐行执行* 2、return语句一旦执行,整个方法必须结束* 可以根据反编译结果得出:return语句一定是最后执行的* 并且return的结果不会因为finally中的i++而改变,为啥呢?* 就是因为第一条规则:必须自上而下执行,return语句是在int i = 100下面的* 如果返回的是101,那就是违背了这条规则*/public static int m(){int i = 100;try {return i;} finally {i++;}}}
反编译后的代码
public class ExceptionTest{public StringTest(){}public static void main(String args[]){int result = m();System.out.println(result);}public static int m(){int i = 100;int j = i;i++;return j;Exception exception;exception;i++;throw exception;}}
3.3 如何选择
-
四、常用方法
getMessage():输出异常的简单信息
printStackTrace():打印异常堆栈信息(一般都使用这个)
五、final、finally、finalize
final(关键字)
- final修饰的类无法继承
- final修饰的方法无法覆盖
- final修饰的变量不能重新赋值
- finally(关键字)
- 和try语句块联合使用
- finally中的代码是一定会执行的
- finalize(标识符)
- 编写一个类继承Exception或者RuntimeException
提供两个构造方法,一个无参数的,一个有参数的
public class MyException extends Exception{public MyException() {}public MyException(String message) {super(message);}}
七、异常与方法覆盖问题
- 对编译时异常来说,重写之后的方法不能比重写之前的方法抛出更多(更宽泛)的异常!!!
- 不过一般来说,父类中的方法怎么写,重写后的方法原样写就好了……
