第七章 异常、断言和日志

1.异常分类

  异常对象派生于Throwable类的一个实例。

    

  Error 类层次结构描述了Java运行时系统内部错误和资源耗尽错误。

  RuntimeException: 由程序错误导致的异常(错误的类型转换,数组访问越界,访问null指针)。

  IOException: 程序本身没有问题,但由于像I/O错误导致的异常(尝试打开不存在的文件,尝试在文件尾部后面读取数据,尝试根据给定的字符串查找Class对象,但字符串表示的类不存在)。

2. 非受查异常和受查异常

  Java语言规范将

  1)派生于 Error类 或者 RuntimeException类 的所有异常称为非受查异常

  2)其他所有异常称为受查异常

  编译器会检查是否为所有受查异常提供了处理(抛出或者捕获)。

3. 声明受查异常

  一个方法必须在首部声明所有可能抛出的异常。遇到下面4种情况时应该抛出异常:

  1)调用一个抛出受查异常的方法。

  2)程序运行过程中发现错误,并利用throw语句抛出一个受查异常。

  3)程序出现错误抛出非受查异常。

  4)Java虚拟机和运行时库出现的内部错误。

  如果一个方法有可能抛出多个受查异常类型,那么必须在首部列出所有的异常类型,每个异常用逗号隔开。

  tips: 子类方法声明的受查异常不能比超类方法中声明的异常更通用。如果超类方法没有抛出任何受查异常,子类也不能抛出任何受查异常。

4. 如何抛出异常

  对于一个已经存在的异常类,将其抛出需要创建这个类的对象,将对象抛出。一旦方法抛出了异常,这个方法就不可能返回到调用者。

5. 捕获异常

try{
    ...  //若出现异常将跳过剩余代码
}catch(ExceptionType e){
    handler for this type  //若捕获异常e将进入执行,否则跳过改语句块
}

 

  如果一个异常发生时没有任何地方捕获,程序将会终止执行,并在控制台打印异常信息(异常的类型和堆栈的内容)。

  在catch子句块可以抛出一个异常,这么做的目的是改变异常的类型。

try{
    ...
}catch(SQLException e){
    throw new ServletException("database error: " + e.getMessage());
}

 

6.finally子句

  不管是否有异常被捕获,finally子句中的代码都被执行。

  当finally子句中含有return语句时。假设利用return语句从try语句块中推出。在方法返回前,finally子句的内容将被执行。如果finally子句中也有一个return子句,这个返回值会覆盖原始的返回值。

public static int f(int n){
    try{
        int r = n*n;
        return r;
    }
    finally{
        if(n == 2) return 0;
    }
}
f(2)执行结果为0.

 7. 打印异常堆栈信息

  捕获到异常后常常会发送报警邮件,此时需要完整的异常信息方便定位问题,推荐使用org.apache.commons.lang3.exception.ExceptionUtils:

public class ErrorPrint {

    public static void main(String[] args) {
        File file = new File("//");
        try (InputStream inputStream = new FileInputStream(file)) {
            //
        } catch (IOException e) {
            String errorMsg = ExceptionUtils.getStackTrace(e);
            System.out.println(errorMsg);
        }
    }

}

 

posted @ 2018-07-19 21:53  walker993  阅读(130)  评论(0编辑  收藏  举报