在本文中,您將學習並了解 Java 現象 StackTrace(也稱為呼叫堆疊追蹤)的工作原理。此資訊是為在 Java 語法等級 9 開始時遇到此概念的初學者建構的。 我想你們所有人,至少一次,在使用 IDE 時遇到類似的錯誤,無論是Idea、Eclipse或其他東西。
Exception in thread "main" java.lang.ArithmeticException
at com.example.task01.Test.division(Test.java:10)
at com.example.task01.Test.main(Test.java:6)
正如您可能已經猜到的,這就是我們的追蹤。但不要急於驚慌,現在我們將為您分解這個例子。首先,您需要了解它的工作原理StackTrace
正如Стэк
其名稱所示。在這一點上,我們將詳細討論一下。 在第八級,您已經熟悉了集合並知道它們分為三組Set
- 集合、List
- 列表、Map
- 字典(或映射)。根據 JavaRush (c)。 我們 Stack
是該團體的一部分List
。其運作原理可以描述為LIFO,即後進先出。也就是說,這是一個類似一疊書的清單;為了取出我們Stack
首先放入的元素,我們需要先提取之後再加入清單中的所有元素。如上圖所示,與常規清單不同,ArrayList
我們可以透過索引從清單中取得任何元素。 再次進行強化。Стэка
只能從最後取得元素!而添加到其中的第一個元素位於開頭(或底部,這樣更方便)。Stack
這些是我們的物件具有的 方法push()
- 將元素添加到堆疊頂部。物件pop()
- 傳回堆疊頂部的元素,並在此過程中將其刪除。物件peek()
- 傳回堆疊頂部的元素,但不刪除它。int search()
- 在堆疊上搜尋元素。如果找到,則傳回其距離堆疊頂部的偏移量。否則返回-1。boolean empty()
- 檢查堆疊是否為空。如果堆疊為空則傳回 true。如果堆疊包含元素,則傳回 false。那為什麼Java
需要StackTrace
一個基於操作原理的模型呢Stack
?讓我們來看看下面這個簡單程式執行過程中發生的錯誤範例。
public class Test {
public static void main(String[] args) {
System.out.println(convertStringToInt(null));
}
public static int convertStringToInt(String s) {
int x = Integer.parseInt(s);
return x;
}
}
我們有一個Test
有兩種方法的類別。大家都很熟悉main
,convertStringToInt
其邏輯就是將從外部(即方法main
)接收到的字串轉換為整數類型並傳回int
。正如您所看到的,我們故意傳遞參數而不是帶有某個數字的字串null
。我們的方法無法正確處理該參數並導致錯誤NumberFormatException
。如您所知,程式開始從方法中計算出其工作main
,此時它會建立一個新的Стэк
方法,並為其命名,StackTrace
並將其工作的當前值置於數字1下,然後我們再次轉到該方法convertStringToInt
和程式將我們位置的參數輸入到先前StackTrace
在編號2parseInt
下創建的參數中,然後調用類別中肉眼不可見的方法,這將已經是我們的Integer
元素編號3StackTrace
,在該方法中將添加另一個內部調用到StackTrace
數字4檢查元素是否為null,這將導致錯誤。程式需要顯示我們的錯誤,指示錯誤發生之前的整個轉換鏈。這就是之前用我們的轉換資料創建的那個來幫助她的地方StackTrace
。
Exception in thread "main" java.lang.NumberFormatException: null
at java.base/java.lang.Integer.parseInt(Integer.java:614)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at com.example.task01.Test.convertStringToInt(Solution.java:10)
at com.example.task01.Test.main(Solution.java:6)
在錯誤發生之前,程式會深入研究方法,但是一旦錯誤發生,一切就開始以相反的順序發生。列印描述問題的一行(範例中的 No.1),然後取得新增到我們的最後一個(頂部)值,Стэк
它是第四個值並列印到控制台(範例中的 No.2),然後我們看到問題出現在Integer
第 614 行程式碼的類別中,並呼叫同一類別方法的第 770 行parseInt
(範例中的第 3 行),當新增到該方法時,Стэк
該方法是第 3 行,並且該類別方法,Integer
對我們來說仍然不可見,它已經被我們convertStringToInt
程式第 10 行的方法呼叫了(範例中的第 4 行,新增時是第二個),而它又在第main
6 行(第 5 行)上被調用在範例中以及新增時分別為第一個)。因此,透過Стек
逐步儲存我們調用的方法,我們能夠返回main
並行列印確切導致錯誤的資訊。但這StackTrace
不僅可以處理錯誤,還可以讓我們獲得許多有關應用程式流程的有趣資訊。我們來看第9級主講評論中另一個流行的例子。我們有了程式碼,我會立即附上一張圖片,直觀地展示程式的流程:
public class Test {
public static void main(String[] args) {
method1();
method2();
}
public static void method1() {
//не вызывает ничего
}
public static void method2() {
method3();
method4();
}
public static void method3() {
//не вызывает ничего
}
public static void method4() {
method5();
}
public static void method5() {
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
for (StackTraceElement element:stackTraceElements) {
System.out.println(element.getMethodName());
}
}
}
到這裡,我們的程式就完美地完成了它的工作並結束了。這是我們將在控制台輸出中看到的內容:
getStackTrace
method5
method4
method2
main
Process finished with exit code 0
我們是如何得出這個結論的?第五種方法(從第 20 行開始)發生了什麼?恐怕我能做的最好的就是將用戶Kirill從評論中最受歡迎的解釋(縮寫)添加到講座中。讓我們轉向創建線StackTrace
並逐個分析它:
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
StackTraceElement[]
- 數組類型的指示(在早期階段,您已經了解了像 int[]、String[] 這樣的數組,這裡是相同的)。 stackTraceElements
- 陣列的名稱可以是任何名稱,考慮到一般命名規則,這不會影響工作。 Thread.currentThread()
- 獲取當前線程的鏈接,在該線程中執行我們想要跟踪的方法(目前這並不重要,您將在 Java Core 任務的第 16 級更詳細地分析線程) getStackTrace()
- 我們獲得所有Стэк
被調用的方法(這是的常規getter StackTrace
)現在讓我們看看創建的數組可能對我們有用。我們知道數組儲存有關已執行方法的資訊。(c) 為此,在第 21 行,我們啟動一個修改後的循環(順便for
說forEach
一句,對於那些還沒有研究過這個循環的人,我建議您閱讀它)並將數據從數組輸出到控制台,即有關在使用構造的工作期間執行了哪些方法的資訊element.getMethodName()
。 請注意,正如我們所看到的,數組的零元素分別是其自身,getStackTrace()
因為在接收資料數組時,它是最後一個執行的方法,因此最終位於頂部Стэка
,並記住我們的構造“ “後進先出”立即第一個加入到數組中的零元素下。以下是我們還可以得到的內容StackTraceElement
: String getClassName()
- 傳回類別的名稱。字串getMethodName()
- 傳回方法的名稱。字串getFileName()
- 傳回檔案名稱(一個檔案中可以有多個類別)。字串getModuleName()
- 傳回模組名稱(可以為空)。字串getModuleVersion()
- 返回模組版本(可以為空)。int getLineNumber()
- 傳回呼叫該方法的檔案中的行號。 現在您已經了解了一般的操作原理,我建議您StackTrace
在您的Ide中親自嘗試不同的方法。即使你還沒有完全掌握所有內容,繼續學習,謎題就會像我在這件事上遇到的那樣。祝大家一切順利!Ps 若您喜歡本篇內容,請按讚支持。這對你來說並不困難,我很高興。謝謝,41 級見;)
GO TO FULL VERSION