1. 程式人生 > >Java 堆疊資訊物件 StackTraceElement,獲取當前執行緒的執行方法

Java 堆疊資訊物件 StackTraceElement,獲取當前執行緒的執行方法

java.langStackTraceElement類儲存了Java中執行緒中的方法棧資訊:

4個屬性:

/**
* 宣告的類,是類的全限定名
*/
private String declaringClass;
/**
* 方法名
*/
private String methodName;
/**
* 檔名一般指:XXX.java
*/
private String fileName;
/**
* XX.java類中的行數
*/
private int    lineNumber;

一個簡單的在SpringBoot 2.0.5-RELEASE 下的示例:

for ( StackTraceElement ele : Thread.currentThread().getStackTrace()) {
    System.out.println("執行緒棧資訊輸出:" + ele.getClassName() + "$" + ele.getMethodName() + "$" + ele.getFileName() + "$" + ele.getLineNumber());
}

輸出結果如下:

執行緒棧資訊輸出:java.lang.Thread$getStackTrace$Thread.java$1559
執行緒棧資訊輸出:com.example.myboot.businessTests.RabbitMQTest$test2$RabbitMQTest.java$54
執行緒棧資訊輸出:sun.reflect.NativeMethodAccessorImpl$invoke0$NativeMethodAccessorImpl.java$-2
執行緒棧資訊輸出:sun.reflect.NativeMethodAccessorImpl$invoke$NativeMethodAccessorImpl.
java$62 執行緒棧資訊輸出:sun.reflect.DelegatingMethodAccessorImpl$invoke$DelegatingMethodAccessorImpl.java$43 執行緒棧資訊輸出:java.lang.reflect.Method$invoke$Method.java$498 執行緒棧資訊輸出:org.junit.runners.model.FrameworkMethod$1$runReflectiveCall$FrameworkMethod.java$50 執行緒棧資訊輸出:org.junit.internal.runners.model.ReflectiveCallable$run$ReflectiveCallable.
java$12 執行緒棧資訊輸出:org.junit.runners.model.FrameworkMethod$invokeExplosively$FrameworkMethod.java$47 執行緒棧資訊輸出:org.junit.internal.runners.statements.InvokeMethod$evaluate$InvokeMethod.java$17 執行緒棧資訊輸出:org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks$evaluate$RunBeforeTestExecutionCallbacks.java$73 執行緒棧資訊輸出:org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks$evaluate$RunAfterTestExecutionCallbacks.java$83 執行緒棧資訊輸出:org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks$evaluate$RunBeforeTestMethodCallbacks.java$75 執行緒棧資訊輸出:org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks$evaluate$RunAfterTestMethodCallbacks.java$86 執行緒棧資訊輸出:org.springframework.test.context.junit4.statements.SpringRepeat$evaluate$SpringRepeat.java$84 執行緒棧資訊輸出:org.junit.runners.ParentRunner$runLeaf$ParentRunner.java$325 執行緒棧資訊輸出:org.springframework.test.context.junit4.SpringJUnit4ClassRunner$runChild$SpringJUnit4ClassRunner.java$251 執行緒棧資訊輸出:org.springframework.test.context.junit4.SpringJUnit4ClassRunner$runChild$SpringJUnit4ClassRunner.java$97 執行緒棧資訊輸出:org.junit.runners.ParentRunner$3$run$ParentRunner.java$290 執行緒棧資訊輸出:org.junit.runners.ParentRunner$1$schedule$ParentRunner.java$71 執行緒棧資訊輸出:org.junit.runners.ParentRunner$runChildren$ParentRunner.java$288 執行緒棧資訊輸出:org.junit.runners.ParentRunner$access$000$ParentRunner.java$58 執行緒棧資訊輸出:org.junit.runners.ParentRunner$2$evaluate$ParentRunner.java$268 執行緒棧資訊輸出:org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks$evaluate$RunBeforeTestClassCallbacks.java$61 執行緒棧資訊輸出:org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks$evaluate$RunAfterTestClassCallbacks.java$70 執行緒棧資訊輸出:org.junit.runners.ParentRunner$run$ParentRunner.java$363 執行緒棧資訊輸出:org.springframework.test.context.junit4.SpringJUnit4ClassRunner$run$SpringJUnit4ClassRunner.java$190 執行緒棧資訊輸出:org.junit.runner.JUnitCore$run$JUnitCore.java$137 執行緒棧資訊輸出:com.intellij.junit4.JUnit4IdeaTestRunner$startRunnerWithArgs$JUnit4IdeaTestRunner.java$68 執行緒棧資訊輸出:com.intellij.rt.execution.junit.IdeaTestRunner$Repeater$startRunnerWithArgs$IdeaTestRunner.java$47 執行緒棧資訊輸出:com.intellij.rt.execution.junit.JUnitStarter$prepareStreamsAndStart$JUnitStarter.java$242 執行緒棧資訊輸出:com.intellij.rt.execution.junit.JUnitStarter$main$JUnitStarter.java$70

從結果中我們可以看出, 棧頂是Thread的getStackTrace方法,這個很好理解。Thread.currentThread().getStackTrace()[1] 是當前執行檢視堆疊資訊的方法RabbitMQTest的test2。 棧底是 JUnitStarter的main 方法,然後我們看到實際呼叫了 org.springframework.test.context.junit4.SpringJUnit4ClassRunner的run 方法。