【发布时间】:2021-11-02 23:40:03
【问题描述】:
在 Java 中,堆栈跟踪是在构造异常时生成的,而不是在抛出异常时生成的。有谁知道这个设计背后的原因是什么?
例如,在下面的程序中,我们在方法test1中抛出了一个异常,但是我们在另一个方法中实例化了这个异常,并从main中调用了test1。结果,test1 永远不会出现在堆栈跟踪中:
class ExceptionNewVsThrow {
private static RuntimeException instantiateException() {
return new RuntimeException("Hello");
}
private static void test1(Exception exception) throws Exception {
throw exception;
}
public static void main(String[] args) throws Exception {
Exception exception = instantiateException();
test1(exception);
}
}
Exception in thread "main" java.lang.RuntimeException: Hello
at FSystem.experimental.exceptions.ExceptionNewVsThrow.instantiateException(ExceptionNewVsThrow.java:18)
at FSystem.experimental.exceptions.ExceptionNewVsThrow.main(ExceptionNewVsThrow.java:26)
见Are stack traces generated when a Java exception is thrown?
【问题讨论】:
-
只是在这里猜测一下:有时异常会被捕获并重新抛出。您通常希望堆栈跟踪在重新抛出后保持原样,对吗?所以也许他们采用了这种设计,这样他们就不必区分初始投掷和重新投掷。此外,构造一个异常而不立即抛出它是不寻常的,因此通常构造时的堆栈跟踪和初始抛出时的堆栈跟踪大致相同。
-
也许你在这里做点什么。如果 throw 语句生成堆栈跟踪,那么程序将更难以控制堆栈跟踪的生成和内容。例如,当构造异常时,您可以使堆栈跟踪无效或首先阻止它生成。如果 throw 语句影响它会更困难
-
异常并不意味着随身携带——它们是异常并且是即时的。从抛出它们的位置构造堆栈跟踪没有任何意义:您可以从任意一组代码路径中添加(或删除)任意级别的堆栈信息,从而显着降低它们的用处。
标签: java exception constructor stack-trace throw