异常的小复习

异常

  1. Throwable

    • Error
    • Exception(异常)
      • 编译时异常(非运行时异常)(编译阶段就会报错,必须处理,否则编译不能通过(抛异常))
      • RuntimeException(运行时异常,运行阶段)
  2. Error与Exception

    • Error:无法通过处理的错误,比如内存崩溃、JVM本身的崩溃…
    • Exception:异常,需要提取处理,使程序更健壮
  3. Java默认异常的自动处理

    • 默认会在出现异常的代码那里自动创建一个异常对象ArithmeticException
    • 会从方法中出现异常的那一行抛出给调用者
    • 调用者最终抛给JVM
    • JVM收到异常对象后,先输出异常栈信息
    • 然后干掉程序
  4. 编译时异常处理:

    • 一股脑的在方法后抛出
    • try …catch 直接printStackTrace异常栈
      (建议直接catch(Exception e))
    • 把异常一层层抛给最外层统一处理(规范)(异常打印不一定按照顺序(会有指令优化,指令重排序))
  5. 运行时异常处理:(10 / 0)

  • 外层要try catch捕获一下
  1. 自定义编译时异常:
    • 继承Exception
    • 重写构造
    • 在出现异常的地方throw new 异常 来抛出
  2. 自定义运行时异常:
  • 继承RuntimeException
  1. try、catch、finally:

    • try只能出现一次
      catch 0-n次(当有finally时可以为0次)
      finally 0-1次 无论代码是否异常,finally都会执行

    • 当多异常处理时,前面catch的异常不能是后面catch异常的父类

    • finally 主要是为了释放资源(资源:实现了Closeable接口的)

    • 如果try有return,要finally执行完才return

    • 在finally中抛异常或者return,会掩盖之前的异常

    • 如果finally有异常,如io流的关闭,try里面先if判断,不为空则关闭,catch里面不打印或者写进日志

  2. 常见的运行时异常

    • 数组越界:ArrayIndexOutOfBoundsException
    • 空指针:NullPointerException(直接输出没问题,调用其功能抛异常)
    • 类型转换异常:ClassCastException
    • 迭代器遍历没有此元素异常:NoSuchElementException
    • 数学操作异常:ArithmeticException
    • 数学转换异常:NumberFormatException
  3. throw 与 throws 的区别

    • throw抛出实例,throws在方法后
    • 如果throw抛出RuntimeException及其子类,则方法声明上可以没有throws,如果throw抛出Exception及其子类,则声明上必须有throws
  4. Java 异常链

    • 异常链是指在进行一个异常处理时抛出了另外一个异常,由此产生了一个异常链条,大多用于将受检查异常(checked exception)封装成为非受检查异常(unchecked exception)或者 RuntimeException。特别注意如果你因为一个异常而决定抛出另一个新的异常时一定要包含原有的异常,这样处理程序才可以通过 getCause() 和 initCause() 方法来访问异常最终的根源。
    • 例子
      • 定义两个异常类
        1
        public class MyE1 extends Exception {}
        1
        2
        3
        4
        5
        6
        7
        8
        public class MyE2 extends Exception{
        MyE2(Throwable throwable){
        super(throwable);
        }
        MyE2(){
        super();
        }
        }
      • 跑一下
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        public class test {
        public void func() throws MyE2 {
        try {
        func2();
        } catch (MyE1 myE1) {
        myE1.printStackTrace();
        throw new MyE2();
        }
        }
        public void func2() throws MyE1 {
        throw new MyE1();
        }
        @Test
        public void test(){
        try {
        func();
        } catch (MyE2 myE2) {
        myE2.printStackTrace();
        }
        }
        }
        • 运行test的结果:
        • func()里面的throw new MyE2()添加上MyE1的信息 -> throw new MyE2(MyE1)
        • 运行test的结果:
        • 现在可以拿到MyE1的信息了
  5. 未完待续!

没了 :)