这可能是一个很幼稚的问题。
我曾经相信Throwable
中Java
总是包含堆栈跟踪。 这是对的吗? 现在看起来,我捕捉exceptions
没有堆栈跟踪。 是否有意义? 是否有可能赶不堆栈跟踪的异常?
这可能是一个很幼稚的问题。
我曾经相信Throwable
中Java
总是包含堆栈跟踪。 这是对的吗? 现在看起来,我捕捉exceptions
没有堆栈跟踪。 是否有意义? 是否有可能赶不堆栈跟踪的异常?
这有可能赶在Java中Throwable对象没有一个堆栈跟踪:
Throwable(String message, Throwable cause, boolean enableSuppression,boolean writableStackTrace)
构造具有新throwable指定详细信息,原因,启用或禁用抑制,和启用或禁用写堆栈跟踪。
http://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html
对于Java 6:
从Java 6不具备Throwable(String message, Throwable cause, boolean enableSuppression,boolean writableStackTrace)
构造函数,我们可以抑制使用以下技术堆栈跟踪填充(从斯卡拉借来的,来自知道如何慢是Java异常? )
class NoStackTraceRuntimeException extends RuntimeException {
@Override
public synchronized Throwable fillInStackTrace() {
return this;
}
}
用法是一样的: throw new NoStackTraceRuntimeException ()
或者它的亚型。
我们还可以通过扩展做同样Throwable
:
class NoStackTraceThrowable extends Throwable {
@Override
public synchronized Throwable fillInStackTrace() {
return this;
}
}
但是,一个小缺点是,你不再能catch
使用这些例外Exception
,因为这不是亚型Exception
,而是应该抓住NoStackTraceThrowable
或者它的亚型。
更新 :有关在不同usecases性能的一些有趣的统计数据,检查该SO问题
对于Java 7+,这里是一个例外,其中堆栈跟踪可以任选地抑制的例子。
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();
}
}
}
这可以证明有:
try {
throw new SuppressableStacktraceException("Not suppressed", false);
} catch (SuppressableStacktraceException e) {
e.printStackTrace();
}
try {
throw new SuppressableStacktraceException("Suppressed", true);
} catch (SuppressableStacktraceException e) {
e.printStackTrace();
}
这是基于MLContextException从Apache的SystemML ,该代码的可在GitHub在https://github.com/apache/systemml 。
最简单的方法来抑制堆栈跟踪上任何异常
throwable.setStackTrace(new StackTraceElement[0]);
如果该异常有一个原因,你可能需要递归这样做。
这也降低了昂贵的创建堆栈跟踪,尽可能
一个抛出的堆栈跟踪被初始化
Throwable#fillInStackTrace()
,这是由任何构造称为并且因此不能被避免。 当实际栈跟踪被使用的,一个StackTraceElement []被懒惰地在构造
Throwable#getOurStackTrace()
这只会发生,如果该字段Throwable.stackTrace还没有设置。
设置堆栈跟踪到任何非空值,避免了一个StackTraceElement []中的Throwable#getOurStackTrace(建设),并降低了性能损失尽可能地。