Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

วิธีดึง Stack Trace ด้วย Thread ใน Java 9

Java 9 เพิ่มคลาส StackWalker เพื่อให้ standard API สำหรับเข้าถึง current thread stack ใน Java versions ก่อนหน้าใช้ Throwable::getStackTrace, Thread::getStackTrace, และ SecurityManager::GetClassContext เพื่อได้ thread stack

Thread.getStackTrace() method คืนค่า array ของ stack trace elements แทน stack dump ของ thread (StackTraceElement[]) Element แรกของ array แทน top of stack (last method invocation) และ element สุดท้ายแทน bottom of stack (first method invocation)

Syntax

public StackTraceElement[] getStackTrace()

ตัวอย่างโค้ด

import java.lang.StackWalker.Option;

public class GetStackTraceTest {
    public static void main(String args[]) {
        GetStackTraceTest.testPrintCurrnentStackTrace();
        GetStackTraceTest.testShowReflectFrames();
    }
    
    // Get StackTrace using Thread
    public static void testPrintCurrnentStackTrace() {
        StackTraceElement[] stack = Thread.currentThread().getStackTrace();
        for(StackTraceElement element : stack) {
            System.out.println(element);
        }
    }
    
    // SHOW_REFLECT_FRAMES
    public static void print(StackWalker stackWalker) {
        stackWalker.forEach(stackFrame -> System.out.printf(
            "%6d| %s -> %s %n", 
            stackFrame.getLineNumber(), 
            stackFrame.getClassName(), 
            stackFrame.getMethodName()
        ));
    }
    
    public static void testShowReflectFrames() {
        final StackWalker stackWalker = StackWalker.getInstance(Option.SHOW_REFLECT_FRAMES);
        print(stackWalker);
    }
}

ผลลัพธ์

java.base/java.lang.Thread.getStackTrace(Thread.java:1654)
GetStackTraceTest.testPrintCurrnentStackTrace(GetStackTraceTest.java:10)
GetStackTraceTest.main(GetStackTraceTest.java:5)
 17| GetStackTraceTest -> print
 25| GetStackTraceTest -> testShowReflectFrames
  6| GetStackTraceTest -> main

เปรียบเทียบ Thread.getStackTrace() vs StackWalker

คุณสมบัติ Thread.getStackTrace() StackWalker
Return type StackTraceElement[] Stream<StackFrame> (lazy)
Performance Capture entire stack ทันที Lazy - ประมวลผลเมื่อจำเป็น
Filtering Manual (หลัง capture) Built-in (skip, limit, filter)
Class reference ไม่มี (แค่ class name) มี (ด้วย RETAIN_CLASS_REFERENCE)
Reflection frames ไม่แสดง แสดงได้ (SHOW_REFLECT_FRAMES)
Hidden frames ไม่แสดง แสดงได้ (SHOW_HIDDEN_FRAMES)

StackTraceElement Methods


String getClassName()      // Fully qualified class name
String getMethodName()     // Method name
String getFileName()       // Source file name
int getLineNumber()        // Line number
boolean isNativeMethod()   // Is native method
String toString()          // Formatted string

Best Practices

  • ใช้ StackWalker สำหรับ production code - ประสิทธิภาพดีกว่า
  • ใช้ Thread.getStackTrace() สำหรับ simple debugging หรือ legacy code
  • หลีกเลี่ยงการ call stack trace บ่อยๆ ใน hot path
  • พิจารณาใช้ logging framework ที่รองรับ structured logging