Exception and The Stack Trace
What happens when we say 开发者_如何学运维e.printStackTrace();
? Here e
is any Exception
. Does it stop the normal execution and actually remove the activation records from the thread stack to give the stack trace of the exception? Is it a good idea to use it in applications?
It just prints stack trace that is already held by exception object to STDERR. No side effects.
Does it stop the normal execution
No.
and actually remove the activation records from the thread stack to give the stack trace of the exception?
No.
The information has already been captured. This happens in the constructors for Throwable
; i.e. when you new
an exception, not when you throw
it. The Throwable
constructor calls the fillInStackTrace()
native method which takes a snapshot of the stack and stores the resulting StackTraceElement[]
in a private variable that is used later when printing the stack trace.
(For the record, this is specified in the javadoc for the constructors of Throwable
.
Is it a good idea to use it in applications?
Well it is rather expensive and can produce a lot of output. But if you need the stack trace for diagnostic purposes ... do it.
e.printStackTrace();
e
is instance of Throwable
and printStackTrace()
This method prints a stack trace for this Throwable object on the error output stream that is the value of the field System.err
There's nothing particularly clever going on. The Exception
object contains a list of StackTraceElements, and it simply dumps them to stderr when the above is called.
As already said, there's no side effects and you won't introduce any issues per-se with using it in production code. I wouldn't really advise it (in production code) however, simply because in most applications it's much better to use a logger to get finer control of exactly what's logged and where it's logged to.
The stack-trace is loaded via fillInStackTrace
which is a native method that is called in the constructor of Throwable. (Neat tip: this method can be overloaded as a NOP for "signal exceptions" which do not need the rather expensive call to get the stack).
The "freeze" of the stack trace already exists for the Throwable object when it is "caught".
As per the code for java.lang.Throwable shows that fillInStackTrace
is called as the first action of the constructor. The array of StackTraceElement
is for serialization support (this can also be set manually) and as a lazy cache.
Even though that fillInStackTrace
captures the trace it is not loaded into Java objects -- I suppose this allows the implementation to keep it "cheap" -- until it needs to be accessed as a sequence of StackTraceElement
objects (e.g. for printStackTrace
which is done in Java code). The code for Throwable shows this better than I can explain :-)
Happy coding.
精彩评论