Exception without stack trace in Java
这可能是一个非常幼稚的问题。
我曾经认为
在没有堆栈跟踪的情况下,可以捕获Java中的可抛出对象:
Constructs a new throwable with the
specified detail message, cause, suppression enabled or disabled, and
writable stack trace enabled or disabled.
http://docs.oracle.com/javase/7/docs/api/java/lang/throwable.html
对于Java 6:
由于Java 6没有EDCOX1×0的构造函数,所以我们可以用下面的技术来抑制StasTr踪迹填充(借用Scala,从Java异常有多慢就知道了?)
1 2 3 4 5 6 | class NoStackTraceRuntimeException extends RuntimeException { @Override public synchronized Throwable fillInStackTrace() { return this; } } |
用法相同:
我们也可以通过扩展
1 2 3 4 5 6 |
但是,一个小问题是你不能再使用
更新:有关不同用例中性能的一些有趣的统计信息,请检查这个so问题
对于Java 7 +,这里有一个异常的例子,其中可以选择性地抑制堆栈跟踪。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class SuppressableStacktraceException extends Exception { private boolean suppressStacktrace = false; public SuppressableStacktraceException(String message, boolean suppressStacktrace) { super(message, null, suppressStacktrace, !suppressStacktrace); this.suppressStacktrace = suppressStacktrace; } @Override public String toString() { if (suppressStacktrace) { return getLocalizedMessage(); } else { return super.toString(); } } } |
这可以通过以下方式来证明:
1 2 3 4 5 6 7 8 9 10 | try { throw new SuppressableStacktraceException("Not suppressed", false); } catch (SuppressableStacktraceException e) { e.printStackTrace(); } try { throw new SuppressableStacktraceException("Suppressed", true); } catch (SuppressableStacktraceException e) { e.printStackTrace(); } |
这是基于Apache SystemML的MLContextException,其代码在GitHub上提供,网址为https://github.com/apache/systemml。
在任何异常上抑制stacktrace的最简单方法是
1 | throwable.setStackTrace(new StackTraceElement[0]); |
如果异常有原因,您可能需要递归地执行相同的操作。
这也尽可能减少了堆栈跟踪的成本
throwable的stacktrace在中初始化
1 |
这是任何构造函数调用的,因此无法避免。当实际使用stacktrace时,stacktraceElement[]在
1 |
只有在尚未设置字段throwable.stacktrace时才会发生这种情况。
将stacktrace设置为非空值,可以避免在throwable getourstacktrace()中构造stacktraceElement[],并尽可能减少性能损失。