1.为什么要使用异常机制

  • 没有异常机制的两个坏处

    • 逻辑代码和错误处理代码放在一起

    • 程序员本身需要考虑的例外情况比较复杂,对程序员本身要求比较高

  • 常见的异常

    • 用户输入错误

    • 设备错误

    • 硬件问题,比如打印机关掉,服务器问题

    • 磁盘满了

2.异常(Exception)的概念

  • 异常时Java提供的用于处理程序中错误的一种机制
public static void mian(String[] args){
    int i = 1/0;
}

Exception in thread "main" java.lang.ArithmetiException: / by zero
    at lorinda.matrix.main(matrix.java:11)
  • Java是采用面向对象的方式来处理异常的.处理过程:

    • 抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象,停止当前执行路径,并把异常对象提交给JRE

    • 捕获异常:JRE得到该异常后,寻找相应的代码来处理该异常.JRE在方法的调用栈中查找,从生成的异常的方法开始回溯,直到找到相应的异常处理代码为止

                        Throwable
                            |
                       ----------
                       |         |
                     Error     Exception
                       /           / \
                      /           /   \
                   Unchecked   Checked  RuntimeException
                    Exception  Exception     |
                                             |
                                         Unchecked   
                                         Exception         

3.Error

  • Error类层次描述了Java运行时系统内部错误和资源耗尽错误.这类错误是我们无法控制的,同时也是非常罕见的错误.所以在编程中,不去处理这类错误.

  • Error表面系统JVM已经处于不可恢复的崩溃状态中

  • 打开JDK包:java.lang.error \查看他的所有子类

  • 注:我们不需要管理Error

4.Exception

  • 所有异常类的父类,其子类对应了各种各样可能出现的异常事件

  • Runtime Exception(unchecked Exception)

    • 一类特殊的异常,如被0除,数组下标超范围,其产生比较频繁,处理麻烦,如果显式的声明或捕获将会对程序可读性和运行效率影响很大.因此由系统自动检测并将它们交给缺省的异常处理程序(用户可不比对其处理)

    • 常见的Runtime Exception:

      ArithmeticException/NullPointerException/ClassCastException/ArrayIndexOutBoundsException/NumberFormatException

  • Checked Exception

    • 这一类异常,我们必须捕获进行处理

5.try..catch..finally

  • try块

    • 一个try语句必须带有至少一个catch语句块或一个finally语句块

    • 注:当异常处理的代码执行结束后,不会返回到try语句去执行尚未执行的代码

  • catch

    • 每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象

    • 常用方法:

      toString()方法:显示异常的类名和产生异常的原因

      getMessage()方法:只显示产生异常的原因,但不显示类名

      printStackTrace()方法:用来跟踪异常事件发生时堆栈的内容

    • catch捕获异常时的捕获顺序:

      如果异常类之间有继承关系,在顺序安排上需要注意
      ,越是顶层的类,越放在下面.再不然就直接把多余的catch省略掉

  • finally

    有些语句,不管是否发生了异常,都必须执行,那么久可以把这样的语句放到finally语句块中

    通常在finally中关闭程序已打开的资源,比如:文件流,释放数据库连接等

6.try,catch,finally,return执行顺序

  • 执行顺序:

    1. 执行try,catch,给返回值赋值

    2. 执行finally

    3. return

一般不用在finally中使用return

7.声明异常:throws子句

  • 当Checked Exception产生时,不一定立刻处理它,可以再把异常throws出去

  • 如果一个方法抛出多个已检查异常,就必须在方法的首部列出所有的异常,之间以逗号分隔

8.方法重写中声明异常原则

  • 子类声明的异常范围不能超过父类声明的范围

    • 父类没有声明异常,子类也不能

    • 不可抛出原有方法抛出异常类的父类或上层类

9.手动抛出异常:throw子句

  • Java异常类对象在程序执行过程中出现异常时由系统自动生成并抛出,也可以根据需要手动创建并抛出

  • 在捕获一个异常前,必须有一段代码先生成异常对象并把它抛出.这个过程我们可以手动做,也可以由JRE来实现,但是他们调用的都是throw子句

  • 对于一个已经存在异常的类,抛出该类异常对象过程如下:

    • 找到一个合适的异常类

    • 创建一个该类的对象

    • 将对象抛出

10.自定义异常

  • 在程序中,可能会遇到任何标准异常类都没有充分描述清楚的问题,这种情况下可以创建自己的异常类

  • 从Exception类或者它的其他的子类派生一个子类即可

  • 习惯上,定义的类应该包含2个构造器:一个是默认构造器,另一个是带有详细信息的构造器

11.使用异常机制建议

  • 要避免使用异常处理代替错误处理,这样会降低程序的清晰性,并且效率低下

  • 处理异常不可以代替简单测试---只在异常情况下使用异常机制

  • 不要进行小粒度的异常处理---应该将整个任务包装在一个try语句块中

  • 异常往往在高层处理