jdk1.7异常新的构造函数


发表于 2018-01-31 17:30


我是喜欢用异常来控制流程的,所以很多时候,异常对我来说仅仅代表着需要执行某个操作,详细的异常信息对我来说并没有任何作用,因此我需要避免填充异常栈,在以前,我是这么做的:

public static class T1Exception extends Exception {

    @Override
    public  Throwable fillInStackTrace() {
        return this;
    }

}

这样就避免了调用额外的native方法填充异常栈,下面是jdk1.8中的fillInStackTrace方法,

public synchronized Throwable fillInStackTrace() {
  if (stackTrace != null ||
      backtrace != null /* Out of protocol state */ ) {
      fillInStackTrace(0);
      stackTrace = UNASSIGNED_STACK;
  }
  return this;
}

今天无意中在 https://stackoverflow.com/questions/299068/how-slow-are-java-exceptions 这里发现了jdk1.7版本以后,异常类额外提供了一个构造函数:

protected Exception(String message, Throwable cause,
                  boolean enableSuppression,
                  boolean writableStackTrace) {
  super(message, cause, enableSuppression, writableStackTrace);
}

通过控制enableSuppression和writableStackTrace参数,可以避免额外的开销:

protected Throwable(String message, Throwable cause,
                  boolean enableSuppression,
                  boolean writableStackTrace) {
  if (writableStackTrace) {
      fillInStackTrace();
  } else {
      stackTrace = null;
  }
  detailMessage = message;
  this.cause = cause;
  if (!enableSuppression)
      suppressedExceptions = null;
}

最后附上自己的测试结果:

public class TestException {

  // 724
  public static class T1Exception extends Exception {

      @Override
      public Throwable fillInStackTrace() {
          return this;
      }

  }

  // 42485
  public static class T2Exception extends Exception {

  }

  //912
  public static class T3Exception extends Exception {

      public T3Exception() {
          super(null, null, false, false);
      }
  }

  public static void main(String[] args) {
      long start = System.currentTimeMillis();
      for (int i = 0; i < 100000000; i++) {
          try {
              new T3Exception();
          } catch (Exception e) {
          }
      }
      System.out.println(System.currentTimeMillis() - start);
  }
}

分别执行一亿次,T1Excpetion、T2Exception和T3Exception时间分别为724ms、42485ms以及912ms。

这样看来第一种比第三钟时间还短一点,但第三种多了一种选择,更加的灵活,你可以在必要的时候调用fillInStackTrace方法。


搜索