用户工具


异常结构

异常种类

  • Error:程序无法处理的异常(如:OutOfMemoryError)
  • Exception:程序可以处理的异常。还分两种
    • 运行时异常:不需要显示处理也能编译,但最终需要被捕获(如:NullPointerException)
    • 检查异常:需要显示处理或抛出异常,否则编译不通过(如:IOException)
      • java认为Checked异常都是可以被处理(修复)的异常,所以必须强制处理

异常抛出

  • 导致当前流程无法正常继续执行的错误,或者,程序可以处理的错误 → 抛出RunTimeException
    • 空指针
    • 除数为0等等
  • 程序无法处理的错误 → 抛出Error
    • 内存溢出
  • 导致程序永远无法正常工作错误 → 抛出Error
    • 关键数据库ip配置错误

异常处理

  • 如果知道异常如何处理,则捕获并且处理
  • 如果自己不能修复,则继续抛出
  • 遇到检查异常,可以转换成运行时异常
        try {
            FileInputStream in=new FileInputStream("/a.txt");
        } catch (FileNotFoundException e) {
            throw new RuntimeException("file exception");
        }
  • 程序最外层统一处理异常
    • 如果程序种使用了assert,那异常捕获的时候要注意assert的异常类型(Error类型)
        try {
            main(); // 不一定是main函数,这里只最上层的函数
        } catch (RuntimeException e){ // 所有运行时异常在这里统一处理
            System.out.println("handle RuntimeException error here");
        } catch (Error e){ // 如果是junit异常,捕获并处理
            if(e.getClass().toString().contains("junit")) {
                System.out.println("handle junit error here");
            }
            else {  // 如果不是junit异常,则一定是系统级异常,程序已经无法处理,抛出异常,终止程序
                System.out.println("handle error here");
                throw e;
            }
        }

自定义异常

异常是一个比较耗时的操作,异常性能差是因为fillInStackTrace方法,该方法是带锁的并且需要填充线程异常栈信息。 而我们的业务类异常是不需要记录异常栈的,可以考虑覆写fillInStackTrace方法减小性能开支(据说覆写该方法能提高10倍性能)。

class BizException extends Exception{
    public BizException(String message) {
        super(message);
    }

    public Throwable fillInStackTrace() {
        return this;
    }
}