Java中异常结构定义的父类为Throwable,其派生出两个子类别:Error(错误),Exception(异常)
用于标识JRE(Java运行环境)的错误,该类时无法通过程序来解决的。
OutOfMemoryError:堆内存溢出(创建对象过多)
StackOverflowError:栈溢出(递归)
表示程序级别的异常,该类错误是可以通过程序来解决的。
注意:
- 异常时行为、方法、过程的意外结果
- 一个方法如果抛出了异常,这方法就必须声明异常的抛出
- 异常的声明:在方法上声明方法的意外结果
- 异常类一般都继承自Exception
- 调用抛出异常的方法必须要处理异常,有两种方案:第一种是使用try-catch-finally捕获异常并解决异常,第二种是使用throws关键字直接抛出异常
- 如果出现了异常,异常以后的代码不会再执行(除了finally中的代码)
-
Java异常捕获机制的语法
try{ // 可能出现异常的代码片段 } catch(XXXException e){ // 解决问题的代码片段(catch块跟在try块之后,用于捕获并解决异常,catch块可以出现多次) } finally{ /* 不管是否出现异常,总会执行的代码块,通常会使用finally语句作为程序的收尾工作。 finally并不是必须的 */ }
JVM发现要用null去调用一个方法,JVM就会创建一个空指针异常的实例来描述这里发生的意外情况。
在当前行抛出异常后,JVM会检查代码的片段,查看当前代码是否有异常处理机制。当发现代码没有异常处理机制,则将该异常实例抛到当前代码方法之外。当异常逐级抛出main方法之外时,JVM会直接杀掉当前程序,程序退出,异常代码之后的代码就不会在执行。
异常捕获机制的良好习惯:在最后一个catch捕获Exception,以保证可以捕获程序中出现的其他异常,使得程序不会出现闪退的情况。
方法中出现异常之后,会一直往上抛,只要上面有异常处理,那么程序就不会退出
-
finally
-
finally永远会被执行,NullPointerException,StringIndexOutOfBoundsException,ArrayIndexOutOfBoudsException。这些异常都属于RuntimeException异常(非检查时异常),该异常又属于Exception。
-
finally会在程序退出try...catch前调用(比如try...catch中有return ,或者throw时,finally会在这些语句块前执行),所以finally中不应该出现return,因为它会覆盖try...catch中的return
-
-
catch异常有顺序,异常要从小到大,否则会出现编译错误
用于主动抛出异常,通常以下两种情况会主动抛出异常
-
当前语法片段出现了一个不满足业务逻辑情况的异常,需要主动的抛出异常。
// 例如 throw new RuntimeException("异常的原因"); /* XXException e; e.getMessage():异常的原因 e.printStackTrace():异常的详细信息*/
-
当前代码片段出现了一个异常,但是该异常的处理不应该是当前代码负责时,需要主动抛出异常。
即在一个方法中出现的异常不必在当前方法中解决时,可以将异常抛出,由上一层的方法处理
该关键字用于在声明方法时,连同声明方法可能抛出的异常种类,以通知使用者(方法的调用者),在调用该方法时应捕获这些异常。
分为检查异常和非检查异常
RuntimeException及其子类。当程序中抛出了(throw主动抛出)一个RuntimeException及其子类时,编译器会在编译时不检查该类异常是否被处理
除了RuntimeException及其子类,其他的都是检查时异常。当程序中抛出了一个检查异常时,编译时会检查该类异常是否有处理代码,没有的话,就编译不通过。
NullPointerException、StringIndexOutOfBoudsException、ArrayIndexOutOfBoundsException、ClassCastException、NumberFormatException