课时118:异常处理流程
摘要:知道异常的处理格式,想更好的处理异常,不能只知道处理格式,还要了解异常的处理流程。
1.1异常处理的含义
在进行异常处理的时候如果将所有已经知道要产生的异常都进行了捕获,虽然能得到良好的代码结构,但是这种代码编写很麻烦,所以要进行合理异常就必须知道在异常产生之后程序有哪些处理。
1.2产生异常
(1)在程序运行的过程之中才会产生异常,而一旦程序执行中产生了异常之后将自动进行指定类型的异常类对象实例化处理。(Try 语句捕获的是实例化对象)
(2)如果此时程序之中并没有提供有异常处理的支持,则会采用JVM默认异常处理方式,首先进行异常信息的打印,而后直接退出当前的程序;(打印异常信息后,程序中断执行,任何直接结束程序)
(3)此时程序中如果存在有异常处理,那么这个产生的异常类的实例化对象将会被 Try 语句所捕获;
(4)Try 捕获到异常之后与其匹配的 Catch 中的异常类型进行依次的比对,如果此时与 Catch 中的捕获异常类型相同,则认为应该使用此 Catch 进行异常处理,如果不匹配则继续匹配后续的 Catch 类型,如果没有任何的Catch 匹配成功,表示该异常无法进行处理;
(5)不论异常是否处理最终都要执行 Finally 语句,但当执行完成 Finally 的程序之后会进一步判断当前的异常是否处理过,如果处理过,则继续向后执行其它代码,如果没有处理则交由 JVM 进行默认的处理。
通过分析发现在整个的异常处理流程之中实际上操作的是异常类的实例化对象,那么异常类的实例化对象的类型便成为了理解异常处理的核心关键之处,此前接触过了两种异常:
ArithmeticException: |
ArrayIndexOutOfBoundsException |
java.lang.Object java.lang.Throwable java.lang.Exception java.lang.RuntimeException java.lang.ArithmeticException |
java. lang. Object java.lang.Throwable java.lang.Exception java.lang.RuntimeException java.lang.IndexOutOfBoundsException java.lang.ArrayIndexOutOfBoundsException |
可以发现在程序之中可以处理的异常的最大的类型就是 Throwable ,而打开 Throwable 可以观察在此类中提供有两个子类:
(1) Error :此时程序还未执行出现的错误,开发者无法处理;
(2) Exception: 程序中出现的异常,开发者可以处理, 真正在开发之中所需要关注的就是 Exception;(如果产生了算数异常,那算数异常其实就是Exception 的子类)
通过分析可以发现异常产生的时候会产生异常的实例化对象,那么按照对象的引用原则,可以自动向父类转型,那么按照这样的逻辑,实际上所有的异常都可以使用 Exception 来处理。
1.3简化异常处理。
代码:
Public class JavaDemo { Public static void main(string args []) { System.out.println ( "【1】****** 程序开始执行 ******") ; Try { Int x = Integer.parseInt ( args [0] ) ; Int y = Integer.parseInt ( args [1] ) ; System.out.println ( "【2】****** 数学计算: ”+ (x/y)) ; } catch (Exception e ) { //现在捕获的范围太大,底下的都包含了,所以语法有错误 E.printstackTrace () ; } catch (NumberFormatException e ) { E.printstackTrace () ; } catch ( e ) { E.printstackTrace () ; } Finally { System.out.println ( "【F】 不管是否出现异常,我都会执行。“); } System.out.println ( "【3】****** 程序执行完毕******") ; } }
执行结果错误:
结论:如果有多个异常捕获时,把捕获范围大的放在最后,此时也不用其他两个代码了,因为所有的异常都能向上转型。
代码:
Public class JavaDemo { Public static void main(string args []) { System.out.println ( "【1】****** 程序开始执行 ******") ; Try { Int x = Integer.parseInt ( args [0] ) ; Int y = Integer.parseInt ( args [1] ) ; System.out.println ( "【2】****** 数学计算: ”+ (x/y)) ; } catch (Exception e ) { E.printstackTrace () ; } Finally { System.out.println ( "【F】 不管是否出现异常,我都会执行。“); } System.out.println ( "【3】****** 程序执行完毕******") ; }
运行结果如下: 没传参数处理了,传的参数不是数字处理了,传的参数被除数为0也处理了。
当有不确定可能产生那些异常时,这种处理方式是最便捷的。但是这样处理也会产生一个问题(假设有一个项目,这个项目由五百多模块组成,如果出错,只会报一句:对不起我出错了,每个模块可能有8-10个错误,如果都用 Exception 语句,就会得到:对不起我出错了)。
这种异常的处理形式虽然方便,但描述的错误信息不明确,所以分开处理异常是一种更加明确的处理方式。
重点:在以后进行多个异常同时处理的时要把捕获范围大的异常放在捕获范围小的异常之后。