异常不需要在Java堆栈跟踪(Exception without stack trace in Ja

2019-06-14 20:30发布

这可能是一个很幼稚的问题。

我曾经相信ThrowableJava 总是包含堆栈跟踪。 这是对的吗? 现在看起来,我捕捉exceptions 没有堆栈跟踪。 是否有意义? 是否有可能赶不堆栈跟踪的异常?

Answer 1:

这有可能赶在Java中Throwable对象没有一个堆栈跟踪:

Throwable(String message, Throwable cause, boolean enableSuppression,boolean writableStackTrace) 

构造具有新throwable指定详细信息,原因,启用或禁用抑制,和启用或禁用写堆栈跟踪。

http://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html



Answer 2:

对于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问题



Answer 3:

对于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 。



Answer 4:

最简单的方法来抑制堆栈跟踪上任何异常

throwable.setStackTrace(new StackTraceElement[0]);

如果该异常有一个原因,你可能需要递归这样做。

这也降低了昂贵的创建堆栈跟踪,尽可能

一个抛出的堆栈跟踪被初始化

Throwable#fillInStackTrace()

,这是由任何构造称为并且因此不能被避免。 当实际栈跟踪被使用的,一个StackTraceElement []被懒惰地在构造

Throwable#getOurStackTrace()

这只会发生,如果该字段Throwable.stackTrace还没有设置。

设置堆栈跟踪到任何非空值,避免了一个StackTraceElement []中的Throwable#getOurStackTrace(建设),并降低了性能损失尽可能地。



文章来源: Exception without stack trace in Java