[英]Exception and The Stack Trace
What happens when we say e.printStackTrace();
当我们说
e.printStackTrace();
时会发生什么? ? ? Here
e
is any Exception
. 这里
e
是任何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. 它只是将异常对象已经保存的堆栈跟踪打印到STDERR。 No side effects.
没有副作用。
e.printStackTrace();
e
is instance of Throwable
e
是Throwable
实例
and printStackTrace()
和
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
此方法在错误输出流上打印此Throwable对象的堆栈跟踪,该输出是字段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. Exception
对象包含一个StackTraceElements列表,在调用上述方法时,它只是将它们转储到stderr中。
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
; 这发生在
Throwable
的构造函数中; ie when you new
an exception, not when you throw
it. 即当你
new
异常,而不是当你throw
它。 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. Throwable
函数调用fillInStackTrace()
本机方法,该方法获取堆栈快照并将结果StackTraceElement[]
存储在私有变量中,此私有变量稍后在打印堆栈跟踪时使用。
(For the record, this is specified in the javadoc for the constructors of Throwable
. (为便于记录,这是在Javadoc中为
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.
但是,如果出于诊断目的需要堆栈跟踪,请执行此操作。
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. 堆栈跟踪通过
fillInStackTrace
加载, fillInStackTrace
是在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). (整洁的提示:对于“信号异常”,此方法可以作为NOP重载,而无需花费相当昂贵的调用来获取堆栈)。
The "freeze" of the stack trace already exists for the Throwable object when it is "caught". 当Throwable对象被“捕获”时,堆栈跟踪的“冻结” 已经存在 。
As per the code for java.lang.Throwable shows that fillInStackTrace
is called as the first action of the constructor. 按照java.lang.Throwable的代码,将
fillInStackTrace
调用为构造函数的第一个动作。 The array of StackTraceElement
is for serialization support (this can also be set manually) and as a lazy cache. StackTraceElement
数组用于序列化支持(也可以手动设置)并作为惰性缓存。
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 (eg for printStackTrace
which is done in Java code). 即使
fillInStackTrace
捕获了未加载到Java对象中的跟踪(我想这也使实现保持“便宜”),直到需要将其作为StackTraceElement
对象序列访问为止(例如,对于printStackTrace
,这是在Java代码)。 The code for Throwable shows this better than I can explain :-) Throwable的代码比我可以解释的更好地展示了这一点:-)
Happy coding. 快乐的编码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.