Java中没有堆栈跟踪的例外

发布于 2025-02-03 11:36:24 字数 161 浏览 2 评论 0 原文

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

我曾经相信Java 始终中的 Throwable 包含堆栈跟踪。正确吗?

现在看来,我发现了异常没有堆栈跟踪。有意义吗?如果没有堆栈跟踪的情况,是否可能可能捕获异常?

This is probably a very naive question.

I used to believe that a Throwable in Java always contains the stack trace. Is it correct?

Now it looks like that I catch exceptions without the stack trace. Does it make sense? Is it possible to catch an exception without the stack trace?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

尬尬 2025-02-10 11:36:24

可以在没有堆栈跟踪的情况下在Java中捕获可抛件对象:

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


指定的详细消息,原因,抑制启用或禁用,以及
可写的堆栈跟踪启用或禁用

public Throwable fillInStackTrace()

填写执行堆栈跟踪。此方法在此记录
有关堆栈当前状态的可投掷对象信息
当前线程的帧。

如果此抛售的堆栈轨迹不写,请称呼这个
方法没有效果

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

It's possible to catch a Throwable object in Java without a stack trace:

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

Constructs a new throwable with the
specified detail message, cause, suppression enabled or disabled, and
writable stack trace enabled or disabled.

public Throwable fillInStackTrace()

Fills in the execution stack trace. This method records within this
Throwable object information about the current state of the stack
frames for the current thread.

If the stack trace of this Throwable is not writable, calling this
method has no effect
.

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

念三年u 2025-02-10 11:36:24

对于Java 6:

由于Java 6没有可投掷(字符串消息,可投掷原因,布尔值启用,布尔值writableStackTrace)构造函数,我们可以使用以下技术来抑制堆栈填充(从Scala借用,是从Scala借来的)从 Java异常有多慢?

class NoStackTraceRuntimeException extends RuntimeException {
    @Override
    public synchronized Throwable fillInStackTrace() {
        return this;
    }
}

新的NostackTraceruntimeException()或它的子类型。

我们还可以通过扩展抛出

class NoStackTraceThrowable extends Throwable {
    @Override
    public synchronized Throwable fillInStackTrace() {
        return this;
    }
}

但是,一个小问题是您不再可以使用 catch 使用 exception ,因为这是不是异常的子类型,而是应捕获 nostackTractraceThrowable 或它的子类型。

Update :有关在不同用途中性能的一些有趣统计数据,请检查此所以问题

For Java 6:

As Java 6 doesn't have the Throwable(String message, Throwable cause, boolean enableSuppression,boolean writableStackTrace) constructor, we can suppress the stacktrace filling using below technique (borrowed from Scala, came to know from How slow are Java exceptions?)

class NoStackTraceRuntimeException extends RuntimeException {
    @Override
    public synchronized Throwable fillInStackTrace() {
        return this;
    }
}

Usage is same: throw new NoStackTraceRuntimeException (), or it's subtypes.

We can also do the same by extending Throwable:

class NoStackTraceThrowable extends Throwable {
    @Override
    public synchronized Throwable fillInStackTrace() {
        return this;
    }
}

But, a small catch is that you no longer can catch these exception using Exception as this is not subtype of Exception, instead should catch NoStackTraceThrowable or it's subtypes.

Update: For some interesting stats on performance in different usecases, check this SO question

空名 2025-02-10 11:36:24

对于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();
}

这是基于 https://github.com/apache/systemml

For Java 7+, here is an example of an exception where the stack trace can optionally be suppressed.

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();
        }
    }
}

This can be demonstrated with:

try {
    throw new SuppressableStacktraceException("Not suppressed", false);
} catch (SuppressableStacktraceException e) {
    e.printStackTrace();
}
try {
    throw new SuppressableStacktraceException("Suppressed", true);
} catch (SuppressableStacktraceException e) {
    e.printStackTrace();
}

This is based on the MLContextException from Apache SystemML, the code of which is available on GitHub at https://github.com/apache/systemml.

冷夜 2025-02-10 11:36:24

在任何例外,抑制堆栈的最简单方法是,

throwable.setStackTrace(new StackTraceElement[0]);

如果异常有原因,则可能需要递归地进行相同的操作。

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

投掷的堆叠式的堆叠到初始化

Throwable#fillInStackTrace()

,因此任何构造函数都称为,因此无法避免。
stacktracelement [] []

Throwable#getOurStackTrace()

当实际使用堆栈Trace时,只有在field可投掷的情况下,既没有设置了

。将stacktrace设置为任何非零值,避免在可投掷#getourstacktrace()中构造stackTraceElement [],并尽可能减少性能罚款。

The easiest way to suppress the stacktrace on any Exception is

throwable.setStackTrace(new StackTraceElement[0]);

If the exception has a cause, you may need to do the same recursively.

This also reduces the costly creation of the stack trace, as much as possible

The stacktrace for a throwable is initialized in

Throwable#fillInStackTrace()

, which is called by any constructor and thus cannot be avoided.
When the stacktrace actually is used, an StackTraceElement[] is lazily constructed in

Throwable#getOurStackTrace()

which only happens, if the field Throwable.stackTrace was not already set.

Setting the stacktrace to whatever non null value, avoids the construction of the StackTraceElement[] in Throwable#getOurStackTrace() and reduces the performance penalty as much as possible.

请止步禁区 2025-02-10 11:36:24

正如Ng。的答复中暗示的那样,如果您一开始看到堆栈Trace,但由于同样的例外,它消失了,您很可能会看到JVM优化的效果。
在这种情况下,以下问题非常相似。

reccristring例外,而无需堆栈跟踪 - 如何重置?

nullpointerexception in Java in Java in Java in Java in Java in Java in Java in Java in Java in Java in stacktrace no stacktrace

我建议将其启用并首先努力防止错误,或者捕获并更优雅地处理它。

As hinted at in the reply by NG., if you are seeing the stacktrace at first but then it disappears for the same exception, you are most likely seeing the effects of JVM optimization.
In that case, the following questions are very similar.

Recurring Exception without a stack trace - how to reset?

NullPointerException in Java with no StackTrace

You can turn this JVM feature off, but I would recommend keeping it enabled and working towards preventing the error in the first place, or catching it and handling it more gracefully.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文