一、概述

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

    二、继承结构

    异常 - 图1

  • 所有异常都是发生在运行阶段的,编译时异常之所以叫做编译时异常,是因为该种异常必须在编译时进行处理

    三、处理方式

    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中完成对资源的释放/关闭
  • 一道面试题

    1. public class ExceptionTest {
    2. public static void main(String[] args) {
    3. int result = m();
    4. System.out.println(result); // 100
    5. }
    6. /**
    7. * 这里返回的值是100
    8. * @return
    9. * 两条规则:
    10. * 1、方法体中的代码必须遵循自上而下顺序依次逐行执行
    11. * 2、return语句一旦执行,整个方法必须结束
    12. * 可以根据反编译结果得出:return语句一定是最后执行的
    13. * 并且return的结果不会因为finally中的i++而改变,为啥呢?
    14. * 就是因为第一条规则:必须自上而下执行,return语句是在int i = 100下面的
    15. * 如果返回的是101,那就是违背了这条规则
    16. */
    17. public static int m(){
    18. int i = 100;
    19. try {
    20. return i;
    21. } finally {
    22. i++;
    23. }
    24. }
    25. }

    反编译后的代码

    1. public class ExceptionTest
    2. {
    3. public StringTest()
    4. {
    5. }
    6. public static void main(String args[])
    7. {
    8. int result = m();
    9. System.out.println(result);
    10. }
    11. public static int m()
    12. {
    13. int i = 100;
    14. int j = i;
    15. i++;
    16. return j;
    17. Exception exception;
    18. exception;
    19. i++;
    20. throw exception;
    21. }
    22. }

    3.3 如何选择

  • 如果希望调用者来进行处理,则选择throws上抛

    四、常用方法

  • getMessage():输出异常的简单信息

  • printStackTrace():打印异常堆栈信息(一般都使用这个)

    五、final、finally、finalize

  • final(关键字)

    • final修饰的类无法继承
    • final修饰的方法无法覆盖
    • final修饰的变量不能重新赋值
  • finally(关键字)
    • 和try语句块联合使用
    • finally中的代码是一定会执行的
  • finalize(标识符)
    • 是一个Object类中的方法名
    • 该方法由垃圾回收器GC负责调用

      六、自定义异常

  1. 编写一个类继承Exception或者RuntimeException
  2. 提供两个构造方法,一个无参数的,一个有参数的

    1. public class MyException extends Exception{
    2. public MyException() {
    3. }
    4. public MyException(String message) {
    5. super(message);
    6. }
    7. }

    七、异常与方法覆盖问题

  • 对编译时异常来说,重写之后的方法不能比重写之前的方法抛出更多(更宽泛)的异常!!!
  • 不过一般来说,父类中的方法怎么写,重写后的方法原样写就好了……