Java中Exception和Error

Exception和Error简介

  首先我们看下java中Error和Exception的类图,我们从IOError和IOException两个例子出发,可以看到他们的类图如下,发现他们都分别继承了ERROR和Exception,而Error和Exception又分别是Throwable的子类。

   Error和Exception的代码其实都很相似,具体的代码逻辑都在Throwable类中,在Throwable类中定义了如下对象和方法:

StackTraceElement[] stackTrace   //这里便是我们打印出的stackTrace数组
Throwable cause  //定义了造成此Throwable的原因
String detailMessage   //具体的描述,我们在自定义Exception时候传入的string就会被设置到该String对象上
printStackTrace() //try-catch块默认的处理方式,会将错误输入到默认的System.err流中
最佳实践
  • 尽量不要捕获类似 Exception、RuntimeException 这样的通用异常,正确的做法应该是根据情况自定义相应的Exception,如果直接捕获Exception这样的通用异常在SonarQube等工具中都会给出明确提示,以防止捕获到我们不希望捕获到的异常
  • 不要吞掉异常, 如果一段异常被吞掉很可能会导致大家感知不到异常的发生,但是程序依然能继续执行下去,最后发现结果对不上取无从发现问题,笔者之前曾解决了一个因为异常被忽略而程序完成后发现数据对不上的问题,此类问题往往会给开发debug时造成大量的时间浪费,正确的做法应该是输出到error日志中或者直接抛出去
  • 不要使用e.printStackTrace(),因为日志很可能被输出到某个你根本找不到的地方去了
  • 不要通过exception进行流程控制,之前遇到过一些同事喜欢用Exception进行流程控制,其实是完全不可取的,因为jvm在处理Exception的时候往往会触发当前线程的一次快照,对性能有很大的影响
  • 尽量不要捕获Error,Error往往意味着系统出现了严重的错误,即使我们捕获了Error让程序得以继续运行,也并不能真正解决问题
  • 记得用finally去关闭资源