1. รับการติดตามสแต็ก
ภาษาโปรแกรม Java มีหลายวิธีสำหรับโปรแกรมเมอร์ในการรับข้อมูลเกี่ยวกับสิ่งที่เกิดขึ้นในโปรแกรม และไม่ใช่แค่คำพูดเท่านั้น
ตัวอย่างเช่น หลังจากโปรแกรม C++ ถูกคอมไพล์แล้ว โปรแกรมเหล่านั้นจะกลายเป็นไฟล์ขนาดใหญ่หนึ่งไฟล์ที่เต็มไปด้วยรหัสเครื่อง และทั้งหมดที่มีให้สำหรับโปรแกรมเมอร์ในขณะรันไทม์คือแอดเดรสของบล็อกหน่วยความจำที่มีรหัสเครื่องที่กำลังดำเนินการอยู่ ไม่เยอะนะขอบอก
แต่สำหรับ Java แม้ว่าโปรแกรมจะถูกคอมไพล์แล้ว คลาสก็ยังคงเป็นคลาส เมธอดและตัวแปรไม่หายไป และโปรแกรมเมอร์มีหลายวิธีในการรับข้อมูลเกี่ยวกับสิ่งที่เกิดขึ้นในโปรแกรม
การติดตามสแต็ก
ตัวอย่างเช่น ในการดำเนินการของโปรแกรม คุณสามารถค้นหาคลาสและชื่อของเมธอดที่กำลังดำเนินการอยู่ และไม่ใช่เพียงเมธอดเดียวเท่านั้น คุณสามารถรับข้อมูลเกี่ยวกับสายการเรียกใช้เมธอดทั้งหมดจากเมธอดปัจจุบันกลับไปยังmain()
เมธอด
รายการที่ประกอบด้วยเมธอดปัจจุบัน และเมธอดที่เรียกใช้ และเมธอดที่เรียกใช้เมธอดนั้น ฯลฯ เรียกว่าสแต็กเทรซ คุณสามารถรับได้ด้วยคำสั่งนี้:
StackTraceElement[] methods = Thread.currentThread().getStackTrace();
คุณยังสามารถเขียนเป็นสองบรรทัด:
Thread current = Thread.currentThread();
StackTraceElement[] methods = current.getStackTrace();
เมธอดแบบ สแตติกcurrentThread()
ของThread
คลาสจะส่งคืนการอ้างอิงไปยังThread
ออบเจกต์ ซึ่งมีข้อมูลเกี่ยวกับเธรดปัจจุบัน เช่น เธรดปัจจุบันของการดำเนินการ คุณจะได้เรียนรู้เพิ่มเติมเกี่ยวกับเธรดในระดับ 17 และ 18 ของภารกิจJava Core
อ็อบเจกต์ นี้Thread
มีgetStackTrace()
เมธอดซึ่งส่งคืนอาร์เรย์ของStackTraceElement
ออบเจกต์ ซึ่งแต่ละอาร์เรย์มีข้อมูลเกี่ยวกับเมธอด เมื่อนำมารวมกัน องค์ประกอบเหล่านี้ทั้งหมดจะก่อตัวเป็นสแต็กเทรซ
ตัวอย่าง:
รหัส |
---|
|
เอาต์พุตคอนโซล |
|
ดังที่เราเห็นในเอาต์พุตคอนโซลของตัวอย่าง เมธอดgetStackTrace()
ส่งคืนอาร์เรย์ขององค์ประกอบสามรายการ:
getStackTrace()
วิธีการของThread
ชั้นเรียนtest()
วิธีการของMain
ชั้นเรียนmain()
วิธีการของMain
ชั้นเรียน
จากสแต็กเทรซนี้ เราสามารถสรุปได้ว่า:
- เมธอด นี้
Thread.getStackTrace()
ถูกเรียกโดยMain.test()
เมธอดในบรรทัดที่ 11 ของไฟล์ Main.java - เมธอด
Main.test()
ถูกเรียกโดยMain.main()
เมธอดในบรรทัดที่ 5 ของไฟล์ Main.java - ไม่มีใครเรียก
Main.main()
วิธีนี้ - นี่เป็นวิธีแรกในห่วงโซ่ของการโทร
อย่างไรก็ตาม ข้อมูลที่มีอยู่บางส่วนเท่านั้นที่แสดงบนหน้าจอ อย่างอื่นสามารถรับได้โดยตรงจากStackTraceElement
วัตถุ
2.StackTraceElement
ตามชื่อของมันStackTraceElement
คลาสถูกสร้างขึ้นเพื่อเก็บข้อมูลเกี่ยวกับ องค์ประกอบ การติดตามสแต็กนั่นคือวิธีหนึ่งในไฟล์stack trace
.
คลาสนี้มีเมธอดอินสแตนซ์ดังต่อไปนี้:
วิธี | คำอธิบาย |
---|---|
|
ส่งกลับชื่อของชั้นเรียน |
|
ส่งกลับชื่อของวิธีการ |
|
ส่งกลับชื่อของไฟล์ (หนึ่งไฟล์สามารถมีหลายคลาส) |
|
ส่งกลับหมายเลขบรรทัดในไฟล์ที่มีการเรียกใช้เมธอด |
|
ส่งคืนชื่อของโมดูล (สามารถเป็นได้null ) |
|
ส่งคืนเวอร์ชันของโมดูล (สามารถเป็นได้null ) |
พวกเขาสามารถช่วยให้คุณได้รับข้อมูลที่ครบถ้วนมากขึ้นเกี่ยวกับ call stack ปัจจุบัน:
รหัส | เอาต์พุตคอนโซล | บันทึก |
---|---|---|
|
|
ชื่อคลาส ชื่อ เมธอด ชื่อ ไฟล์ ชื่อ บรรทัดหมายเลข โมดูล ชื่อ โมดูล เวอร์ชัน ชื่อคลาส ชื่อ เมธอด ไฟล์ ชื่อบรรทัด หมายเลข โมดูล ชื่อ โมดูล เวอร์ชัน คลาส ชื่อ เมธอด ไฟล์ ชื่อ บรรทัด หมายเลขโมดูล ชื่อ โมดูล เวอร์ชันโมดูล |
3. กอง
คุณรู้อยู่แล้วว่าstack traceคืออะไร แต่stack (Stack class) คืออะไร?
สแต็คเป็นโครงสร้างข้อมูลที่คุณสามารถเพิ่มองค์ประกอบและจากที่คุณสามารถดึงองค์ประกอบได้ ในการทำเช่นนั้น คุณสามารถใช้องค์ประกอบจากจุดสิ้นสุดเท่านั้น: คุณเพิ่มองค์ประกอบสุดท้ายก่อน จากนั้นจึงเพิ่มองค์ประกอบที่สองไปยังองค์ประกอบสุดท้าย ฯลฯ
ชื่อสแต็คเองบ่งบอกถึงลักษณะการทำงานนี้ เช่น วิธีที่คุณจะโต้ตอบกับปึกกระดาษ หากคุณใส่แผ่นที่ 1, 2 และ 3 ในปึก คุณต้องดึงแผ่นเหล่านั้นกลับลำดับ: แผ่นที่สามแผ่นแรก แผ่นที่สอง และแผ่นแรกเท่านั้น
Java ยังมีคลาสคอลเลกชัน Stack พิเศษที่มีชื่อและลักษณะการทำงานเหมือนกัน คลาสนี้มีพฤติกรรมหลายอย่างร่วมกับArrayList
และ LinkedList
แต่ก็มีวิธีการที่ใช้ลักษณะการทำงานของสแต็ก:
วิธีการ | คำอธิบาย |
---|---|
|
เพิ่มobj องค์ประกอบที่ด้านบนของสแต็ก |
|
นำองค์ประกอบจากด้านบนของสแต็ก (ความลึกของสแต็กลดลง) |
|
ส่งกลับรายการที่ด้านบนสุดของสแต็ก (สแต็กไม่เปลี่ยนแปลง) |
|
ตรวจสอบว่าคอลเลกชันว่างเปล่าหรือไม่ |
|
ค้นหาวัตถุในคอลเลกชันและส่งกลับindex |
ตัวอย่าง:
รหัส | เนื้อหาสแต็ก (ด้านบนของสแต็กอยู่ทางขวา) |
---|---|
|
|
สแต็คถูกใช้ค่อนข้างบ่อยในการเขียนโปรแกรม นี่จึงเป็นคอลเลกชั่นที่มีประโยชน์
4. การแสดงสแต็กเทรซระหว่างการจัดการข้อยกเว้น
เหตุใดรายการเรียกเมธอดจึงเรียกว่าสแต็กเทรซ เนื่องจากถ้าคุณคิดว่ารายการเมธอดเป็นปึกกระดาษที่มีชื่อเมธอด เมื่อคุณเรียกเมธอดถัดไป เท่ากับคุณเพิ่มชีตที่มีชื่อเมธอดนั้นลงในสแต็ก และกระดาษแผ่นถัดไปก็วางทับบนนั้นไปเรื่อยๆ
เมื่อเมธอดสิ้นสุดลง แผ่นงานที่อยู่ด้านบนสุดของสแต็กจะถูกเอาออก คุณไม่สามารถนำแผ่นงานออกจากตรงกลางของปึกโดยไม่นำแผ่นงานที่อยู่ด้านบนออกทั้งหมด ในทำนองเดียวกัน คุณไม่สามารถยุติเมธอดระหว่างสายของการโทรโดยไม่ยุติเมธอดทั้งหมดที่เรียก
ข้อยกเว้น
การใช้สแต็คที่น่าสนใจอีกอย่างคือระหว่างการจัดการข้อยกเว้น
เมื่อเกิดข้อผิดพลาดในโปรแกรมและมีข้อผิดพลาดเกิดขึ้นข้อยกเว้นจะประกอบด้วยการติดตามสแต็ก ปัจจุบัน — อาร์เรย์ที่ประกอบด้วยรายการของวิธีการเริ่มต้น จากวิธีการหลักและสิ้นสุดด้วยวิธีการที่เกิดข้อผิดพลาด มีแม้กระทั่งบรรทัดที่เกิดข้อยกเว้น!
การติดตามสแต็กนี้ถูกจัดเก็บไว้ในข้อยกเว้นและสามารถเรียกค้นได้อย่างง่ายดายโดยใช้วิธีการต่อไปนี้:StackTraceElement[] getStackTrace()
ตัวอย่าง:
รหัส | บันทึก |
---|---|
|
จับข้อยกเว้น รับการติดตามสแต็กที่มีอยู่เมื่อเกิดข้อผิดพลาด |
นี่เป็นเมธอดของThrowable
คลาส ดังนั้นลูกหลานของมันทั้งหมด (เช่น ข้อยกเว้นทั้งหมด) มีgetStackTrace()
เมธอด สะดวกสุด ๆ เหรอ?
แสดงการติดตามสแต็กของข้อยกเว้น
อย่างไรก็ตามThrowable
คลาสมีวิธีอื่นสำหรับการทำงานกับสแต็กเทรซ ซึ่งเป็นเมธอดที่แสดงข้อมูลสแต็กเทรซทั้งหมดที่จัดเก็บไว้ในข้อยกเว้น เรียกว่าprintStackTrace()
.
ค่อนข้างสะดวกคุณสามารถเรียกมันได้ทุกข้อยกเว้น
ตัวอย่าง:
รหัส |
---|
|
เอาต์พุตคอนโซล |
|
GO TO FULL VERSION