1

In Java, stack traces are generated when an exception is constructed, not when it's thrown. Does anyone know what's the reasoning behind this design?

For example, in the following program, we throw an exception in method test1, but we instantiate the exception in another method, and call test1 from main. As a result, test1 never shows up in the stack trace:

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)

See Are stack traces generated when a Java exception is thrown?

claude
  • 99
  • 8
  • 2
    Just taking a guess here: sometimes exceptions get caught and re-thrown. You usually want the stack trace kept as it was after the re-throw, right? So maybe they went with this design so they wouldn't have to differentiate an initial throw from a re-throw. Also, it's unusual to construct an exception and not throw it immediately, so usually the stack trace at construction and the stack trace at initial throw are about the same. – jason44107 Sep 05 '21 at 17:24
  • Maybe you are on to something here. If a throw statement generates the stack trace, then it would be more difficult for the program to control the stack trace generation and contents. For example, when the exception is constructed, you can nullify the stack trace or prevent it from being generated in the first place. It would be more difficult if the throw statement affected it – claude Sep 05 '21 at 18:55
  • Exceptions aren't meant to be carried around--they're *exceptional* and immediate. It wouldn't make any sense to construct the stack trace from where they're thrown: you might add (or remove) arbitrary levels of stack information from an arbitrary set of code paths, making them significantly less useful. – Dave Newton Sep 06 '21 at 04:02

2 Answers2

0

This is the Java language specification for the throws statement : https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.18

And it seems that the throws statement simply throws the exception; it doesn’t build the stack trace that goes into it. Based on the methods for setting the exception (class Throwable) it looks like Java is giving the developer the responsibility of building the exception, initializing it’s cause and stack trace, etc. So if this was part of throws, the developer wouldn’t have the same flexibility.

Therefore, the answer to the question is : it is more powerful and flexible to build stack traces as part of Exception construction.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
claude
  • 99
  • 8
0

In Java, stack traces are generated when an exception is constructed, not when it's thrown. Does anyone know what's the reasoning behind this design?

I don't think we can give you the full (original) reasoning because the decisions were most likely made back in the days when Java was called Oak (!)

But a couple of advantages are:

  • When you rethrow an exception, the original stacktrace is preserved. So for example, you can catch an exception on one thread, pass it to another thread and rethrow it ... with the original stacktrace.
  • You can do things in a custom exception's implementation to change the way that the stacktrace is created; e.g. you can suppress it entirely. Or you could potentially "massage" the stacktrace to hide secret internal details from your customers.
  • Capturing the stacktrace is expensive. So if the throw statement captured it, there wouldn't be any opportunity to save the expense of capturing it. (Admittedly, modern JVMs have another way of dealing with this ... but we are talking about the original design decisions here.)
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216