This is assuming we don't call the .printstacktrace method - just throwing and catching.
We are considering this for some performance bottlenecks.
This is assuming we don't call the .printstacktrace method - just throwing and catching.
We are considering this for some performance bottlenecks.
No, stack traces are generated when exception object is constructed, not when it's thrown. The Throwable() constructors call fillInStackTrace(). (At least in Sun/Oracle's JDK 6 for Windows.)
Stacktrace is captured when exception is constructed.
If you really don't care about stacktrace, you can construct an exception once and throw it multiple times, but it looks like a hack and can be confusing.
A Throwable object captures the current stack (using native code) if it will be printed or not. That's the reason why Exceptions shouldn't be (ab)used for control flow.
it is not built lazily when the printStackTrace() method is called
Neal Gafter (former Sun engineer on the team that builds Java) mentioned exception performance here:
The most expensive part of exception handling by far is capturing the stack trace when creating the exception
Also, see this question.
As answered above, stack traces are NOT generated when an exception is thrown. Rather, they are generated when the exception is constructed. I've tested it below. In my opinion this is not intuitive. The place where something wrong happens is the place where the exception is thrown, not where it's constructed.
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);
}
}
And the output is:
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)
Notice how the stack trace mentions main and instantiateException, but not test1
FYI. You can overload fillInStackTrace to avoid the performance penalty. We do this at twitter when we want for certain exceptions where we do not care about a stack trace.
play framework also does this in play 1.3.x line.
Also, you can breakpoint fillInStackTrace to see it is done at construction.