异常、断言和日志

异常

Throwable类

  • Exception和Error都派生于Throwable类

Exception类

  • 异常有两个分支:
    1. RuntimeException运行时异常,一般为程序错误导致:比如:
    • 错误的强制类型转换
    • 数组访问越界
    • 访问null指针
    1. 其他异常(也称为检查型异常):需要主动处理这类异常。比如
    • 文件异常IOException
    • Class未找到异常

声明异常

  • 在方法首部通过throws抛出所有检查型异常,非检查型异常应该自行处理
  • 子类覆盖超类方法时,抛出的检查型异常不能比超类的大

捕获异常

  • 多个不存在继承关系的异常可以合并到同一个catch块,用 “|” 分隔
  • 多个catch块声明的异常类型,超类不能在子类之前,否则永远进不了子类catch块
  • catch块中可以再次抛出异常,通常用于改变异常类型,建议将原始异常设置为新异常的“原因”,这样在捕获到新异常时不会丢失原始异常的细节
  • 一个方法中发生了检查型异常,但这个方法不允许抛出检查型异常(比如父类方法没有抛出检查型异常),就可以包装成一个运行时异常,将检查型异常添加到新一场的原因中

finally

  • 不论try块有没有抛出异常,或者catch块是否捕获到异常,或者catch块有没有再次抛出异常,finally块的代码都将执行
  • 常用于释放资源
  • 可以只有try-finally,没有catch块
  • finally块中如果有return语句,将会改变流程,覆盖try中的return

try-with-resources语句

try(Resource res=...){
...
}
  • 如果资源实现了AutoCloseable接口,在处理资源时可以替代在finally中释放资源的办法,try块结束后会自动关闭资源
  • 在原始的 try-finally方式中关闭资源,finally也可能抛出异常,这就很麻烦,try-with-resources方式如果在关闭资源时发生异常,会将close异常自动添加到try块的原始异常中,重新抛出原始异常
  • 可以有catch块,也可以有finally块,在关闭资源后执行

日志

基本日志

  • 全局日志记录器:Logger.getGlobal()
  • 默认记录器日志级别为INFO
  • 默认日志处理器时ConsoleHandle,默认日志级别是INFO

高级日志

  • 日志级别
    1. SEVERE
    2. WARNING
    3. INFO
    4. CONFIG
    5. FINE
    6. FINER
    7. FINEST
  • 设置日志记录器级别:logger.setLevel(Level)
  • 设置日志处理器级别:handle.setLevel(Level),日志处理器级别不能高于日志记录器级别,否则会过滤

修改日志管理器配置

  • 配置文件位于jre/lib/logging.properties(Java9之前)
  • 可以修改默认日志记录器、日志处理器级别
  • 可以自定义配置日志记录器、日志处理器

过滤器

  • 除了日志级别的过滤,每个日志记录器和日志处理器都可以配置一个过滤器来完成过滤
  • 过滤器要实现Filter接口,再调用setFilter()方法设置

格式化器

  • 实现了Formatter接口
  • 日志处理器通过setFormatter设置自定义格式化

日志技巧

  • 开发中尽量将日志级别设置到INFO以下,线上环境再设置为INFO,就可以过滤掉开发中的一些调试日志

调试技巧

  • 创建一个日志代理类,将方法调用信息打印出来

  • 打印异常对象的堆栈轨迹 e.printStackTrace

  • 在代码中打印当前调用轨迹 Thread.dumpStack()

  • 将异常堆栈轨迹转换成字符串:

StringWriter out = new StringWriter();
new Throwable().printStackTrace(new PrintWriter(out));
String description = out.toString();
posted @ 2022-09-28 14:29  扣jio大汉子  阅读(44)  评论(0)    收藏  举报