- 异常:程序在执行过程中所产生的问题。
- 异常的分类:
- 检查异常:用户错误或者不能被程序员所预见的问题,也称为编译时异常
- 运行时异常:程序在运行过程中可能发生的、可以被程序员避免的异常类型
- 错误:用户或程序员无法控制的问题
- 异常的控制流程
- 捕获异常,不让它沿着调用栈继续向下抛出
- 捕获异常,并继续向下抛出
- 不捕获异常,异常对象继续抛给调用栈下面的main方法
- 异常层次结构图:
5. 异常的处理机制:
- 捕获异常:
try、catch 和 finally
- try-catch-finally 规则(异常处理语句的语法规则):
1) 必须在 try 之后添加 catch 或 finally 块。try 块后可同时接 catch 和 finally 块,但至少有一个块。
2) 必须遵循块顺序:若代码同时使用 catch 和 finally 块,则必须将 catch 块放在 try 块之后。
3) catch 块与相应的异常类的类型相关。
4) 一个 try 块可能有多个 catch 块。
5) 在 try-catch-finally 结构中,可重新抛出异常。
6) 除了System.exit(int),总将执行 finally 做为结束:
- try、catch、finally语句块的执行顺序:
1)当try没有捕获到异常时:try语句块中的语句逐一被执行,程序将跳过catch语句块,执行finally语句块和其后的语句;
2)当try捕获到异常,catch语句块里没有处理此异常的情况:当try语句块里的某条语句出现异常时,而没有处理此异常的catch语句块时,此异常将会抛给JVM处理,finally语句块里的语句还是会被执行,但finally语句块后的语句不会被执行;
3)当try捕获到异常,catch语句块里有处理此异常的情况:在try语句块中是按照顺序来执行的,当执行到某一条语句出现异常时,程序将跳到catch语句块,并与catch语句块逐一匹配,找到与之对应的处理程序,其他的catch语句块将不会被执行,而try语句块中,出现异常之后的语句也不会被执行,catch语句块执行完后,执行finally语句块里的语句,最后执行finally语句块后的语句;
6.throw抛出异常:
如果一个方法可能会出现异常,但没有能力处理这种异常,可以在方法声明处用throws子句来声明抛出异常。
throws语句用在方法定义时声明该方法要抛出的异常类型,如果抛出的是Exception异常类型,则该方法被声明为抛出所有的异常。多个异常可使用逗号分割。
使用throws关键字将异常抛给调用者后,如果调用者不想处理该异常,可以继续向上抛出,但最终要有能够处理该异常的调用者。test throws Exception1,Exception2,..,ExceptionN { }
抛出异常的规则:
1) 如果是不可查异常(unchecked exception),即Error、RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,编译仍能顺利通过,但 在运行时会被系统抛出。
2)如果一个方法可能出现检查时异常,要么用try-catch语句捕获,要么用throws子句声明将它抛出,否则会导致编译错误
3)当抛出了异常,该方法的调用者必须处理或者重新抛出该异常。当方法的调用者无力处理该异常的时候,应该继续抛出。
4)调用方法必须遵循检查时异常的处理和声明规则。若覆盖一个方法,则不能声明与覆盖方法不同的异常。声明的任何异常必须是被覆盖方法所声明异常的同类或子类。