2011-02-10 290 views
0

當我們說e.printStackTrace();時會發生什麼?這裏e是任何Exception。它是否會停止正常執行並實際從線程堆棧中移除激活記錄以給出異常的堆棧跟蹤?在應用程序中使用它是一個好主意嗎?異常和堆棧跟蹤

+1

堆棧跟蹤是創建異常時的線程堆棧,而不是它打印的地方/記錄。 – 2011-02-10 14:30:04

回答

2

它停止正常執行

,實際上從線程堆棧中刪除的活動記錄給異常的堆棧跟蹤?

No.

該信息已被捕獲已被捕獲。這發生在Throwable的構造函數中;即當你new出現異常,而不是你throw的時候。 Throwable構造函數調用fillInStackTrace()本地方法,該方法獲取堆棧的快照,並將生成的StackTraceElement[]存儲在稍後打印堆棧跟蹤時使用的專用變量中。

(根據記錄,這是的Javadoc的Throwable構造函數指定。

這是個好主意,在應用程序中使用它?

那麼它是相當昂貴的,可以產生大量的輸出但是如果你需要需要用於診斷目的的堆棧跟蹤......做到這一點

3

e.printStackTrace();

eThrowable

printStackTrace()

實例時,該方法將打印一個堆棧跟蹤在作爲場系統的值的誤差輸出流此Throwable對象。 err

+0

標準錯誤,不是標準輸出。儘管在大多數情況下它並不重要 – AlexR 2011-02-10 13:04:31

+0

@AlexR是同意 – 2011-02-10 13:04:54

4

它只是打印堆棧軌跡這已經由異常對象持有到STDERR。無副作用。

+0

一個小副作用是堆棧跟蹤在出於性能原因使用之前未被填充,通常不使用堆棧跟蹤。它存儲在其他地方,但在代碼中使用之前,您無法在調試器中看到它。 – 2011-02-10 14:31:19

+0

@Peter Lawrey在「本地某處」的其他地方,但「本地某處」通常填充了「fillInStackTrace」,它已經具有記錄堆棧的「成本」。這只是將其從原生地方拖到被繞過的StackTraceElement對象的「成本」。 – 2011-02-10 14:49:36

3

沒有什麼特別聰明的事情發生。 Exception對象包含一個StackTraceElements的列表,並且在調用上述內容時它將它們簡單地轉儲到stderr。

0

如前所述,沒有副作用,在生產代碼中不會引入任何問題。然而,我並不真正告訴它(在生產代碼中),只是因爲在大多數應用程序中使用記錄器來更好地控制記錄的內容以及記錄的位置會更好。

0

堆棧跟蹤通過fillInStackTrace加載,這是在Throwable的構造函數中調用的本地方法。 (整潔的提示:這種方法可以作爲「信號異常」的NOP來重載,而不需要相當昂貴的調用來獲得堆棧)。

堆棧跟蹤的「凍結」對於 Throwable對象在「被捕獲」時已經存在。

根據java.lang.Throwable的代碼顯示fillInStackTrace被稱爲構造函數的第一個動作。 StackTraceElement的數組用於序列化支持(這也可以手動設置)並作爲惰性緩存。

即使是fillInStackTrace捕獲跟蹤它加載到Java對象 - 我想這允許執行,以保持它「便宜」 - 直到它需要爲StackTraceElement對象的順序被訪問(例如對於在Java代碼中完成的printStackTrace)。 Throwable的代碼比我能解釋得更好:-)

快樂編碼。