1.16 Java的异常跟踪栈
異常對象的 printStackTrace() 方法用于打印異常的跟蹤棧信息,根據(jù) printStackTrace() 方法的輸出結(jié)果,開發(fā)者可以找到異常的源頭,并跟蹤到異常一路觸發(fā)的過程。
看下面用于測試 printStackTrace 的例子程序。
class SelfException extends RuntimeException {SelfException() {}SelfException(String msg) {super(msg);} } public class PrintStackTraceTest {public static void main(String[] args) {firstMethod();}public static void firstMethod() {secondMethod();}public static void secondMethod() {thirdMethod();}public static void thirdMethod() {throw new SelfException("自定義異常信息");} }上面程序中 main 方法調(diào)用 firstMethod,firstMethod 調(diào)用 secondMethod,secondMethod 調(diào)用 thirdMethod,thirdMethod 直接拋出一個 SelfException 異常。運行上面程序,會看到如下所示的結(jié)果。
Exception in thread "main" Test.SelfException: 自定義異常信息at Test.PrintStackTraceTest.thirdMethod(PrintStackTraceTest.java:26)at Test.PrintStackTraceTest.secondMethod(PrintStackTraceTest.java:22)at Test.PrintStackTraceTest.firstMethod(PrintStackTraceTest.java:18)at Test.PrintStackTraceTest.main(PrintStackTraceTest.java:14)上面運行結(jié)果的第 2 行到第 5 行之間的內(nèi)容是異常跟蹤棧信息,從打印的異常信息我們可以看出,異常從 thirdMethod 方法開始觸發(fā),傳到 secondMethod 方法,再傳到 firstMethod 方法,最后傳到 main 方法,在 main 方法終止,這個過程就是 Java 的異常跟蹤棧。
在面向?qū)ο蟮木幊讨?#xff0c;大多數(shù)復雜操作都會被分解成一系列方法調(diào)用。這是因為實現(xiàn)更好的可重用性,將每個可重用的代碼單元定義成方法,將復雜任務逐漸分解為更易管理的小型子任務。由于一個大的業(yè)務功能需要由多個對象來共同實現(xiàn),在最終編程模型中,很多對象將通過一系列方法調(diào)用來實現(xiàn)通信,執(zhí)行任務。
所以,面向?qū)ο蟮膽贸绦蜻\行時,經(jīng)常會發(fā)生一系列方法調(diào)用,從而形成“方法調(diào)用?!?#xff0c;異常的傳播則相反:只要異常沒有被完全捕獲(包括異常沒有被捕獲,或異常被處理后重新拋出了新異常),異常從發(fā)生異常的方法逐漸向外傳播,首先傳給該方法的調(diào)用者,該方法調(diào)用者再次傳給其調(diào)用者……,直至最后傳到 main 方法,如果 main 方法依然沒有處理該異常,則 JVM 會中止該程序,并打印異常的跟蹤棧信息。
很多初學者一看到上面運行結(jié)果的異常提示信息,就會驚慌失措,其實結(jié)果中的異常跟蹤棧信息非常清晰,它記錄了應用程序中執(zhí)行停止的各個點。
異常跟蹤棧信息的第一行一般詳細顯示異常的類型和異常的詳細消息,接下來是所有異常的發(fā)生點,各行顯示被調(diào)用方法中執(zhí)行的停止位置,并標明類、類中的方法名、與故障點對應的文件的行。一行行地往下看,跟蹤??偸亲顑?nèi)部的被調(diào)用方法逐漸上傳,直到最外部業(yè)務操作的起點,通常就是程序的入口 main 方法或 Thread 類的 run 方法(多線程的情形)。
下面例子程序示范了多線程程序中發(fā)生異常的情形。
public class ThreadExceptionTest implements Runnable {public void run() {firstMethod();}public void firstMethod() {secondMethod();}public void secondMethod() {int a = 5;int b = 0;int c = a / b;}public static void main(String[] args) {new Thread(new ThreadExceptionTest()).start();} }運行上面程序,會看到如下運行結(jié)果。
Exception in thread "Thread-0" java.lang.ArithmeticException: / by zeroat Test.ThreadExceptionTest.secondMethod(ThreadExceptionTest.java:14)at Test.ThreadExceptionTest.firstMethod(ThreadExceptionTest.java:8)at Test.ThreadExceptionTest.run(ThreadExceptionTest.java:4)at java.lang.Thread.run(Unknown Source)多線程異常的跟蹤棧,從發(fā)生異常的方法開始,到線程的 run 方法結(jié)束。從上面的運行結(jié)果可以看出,程序在 Thread 的 run 方法中出現(xiàn)了 ArithmeticException 異常,這個異常的源頭是 ThreadExcetpionTest 的 secondMethod 方法,位于 ThreadExcetpionTest.java 文件的 14 行。這個異常傳播到 Thread 類的 run 方法就會結(jié)束(如果該異常沒有得到處理,將會導致該線程中止運行)。
前面已經(jīng)講過,調(diào)用 Exception 的 printStackTrace() 方法就是打印該異常的跟蹤棧信息,也就會看到上面兩個示例運行結(jié)果中的信息。當然,如果方法調(diào)用的層次很深,將會看到更加復雜的異常跟蹤棧。
提示:雖然 printStackTrace() 方法可以很方便地用于追蹤異常的發(fā)生情況,可以用它來調(diào)試程序,但在最后發(fā)布的程序中,應該避免使用它。應該對捕獲的異常進行適當?shù)奶幚?#xff0c;而不是簡單地將異常的跟蹤棧信息打印出來。
總結(jié)
以上是生活随笔為你收集整理的1.16 Java的异常跟踪栈的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1.15 异常处理规则
- 下一篇: 1.17 Java.util.loggi