日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

得到当前堆栈信息的两种方式(Thread和Throwable)的方法

發布時間:2024/9/30 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 得到当前堆栈信息的两种方式(Thread和Throwable)的方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天看到有一個工具類中有一句

Thread.currentThread().getStackTrace()[2].getClassName();


原來工作中遇到的問題:使用Thread.currentThread().getStackTrace()[1].getClassName()得到的是當前類而不是調用類。

所以弄個明白 。

我進行了一組測試:

測試A:

public class ThreadTest {public static void TestString(){StackTraceElement[] arr = new Exception().getStackTrace();for(int i=0;i<=arr.length-1;i++){System.out.println(arr[i].getClassName()+";"+arr[i].getMethodName()+";"+arr[i].getFileName());}} } public class App {public static void main( String[] args ){ThreadTest.TestString();} }

? ? ?結果是:

test.ThreadTest;TestString;ThreadTest.java(當前方法和類)

test.App;main;App.java(調用該方法的方法和類)

測試B:

public class ThreadTest {public static void TestString(){StackTraceElement[] arr = Thread.currentThread().getStackTrace();for(int i=0;i<=arr.length-1;i++){System.out.println(arr[i].getClassName()+";"+arr[i].getMethodName()+";"+arr[i].getFileName());}} }

App類同上,得到的結果是:

java.lang.Thread;getStackTrace;Thread.java(Thread的信息)

test.ThreadTest;TestString;ThreadTest.java(當前方法和類)

test.App;main;App.java(調用該方法的方法和類)

查看了下jdk的源碼。

首先是Throwable的getStackTrace方法,代碼如下:

public StackTraceElement[] getStackTrace() {return getOurStackTrace().clone();}private synchronized StackTraceElement[] getOurStackTrace() {// Initialize stack trace field with information from// backtrace if this is the first call to this methodif (stackTrace == UNASSIGNED_STACK ||(stackTrace == null && backtrace != null) /* Out of protocol state */) {int depth = getStackTraceDepth();stackTrace = new StackTraceElement[depth];for (int i=0; i < depth; i++)stackTrace[i] = getStackTraceElement(i);} else if (stackTrace == null) {return UNASSIGNED_STACK;}return stackTrace;}

再看下Thread的getStackTrace方法,代碼如下:

public StackTraceElement[] getStackTrace() {if (this != Thread.currentThread()) {// check for getStackTrace permissionSecurityManager security = System.getSecurityManager();if (security != null) {security.checkPermission(SecurityConstants.GET_STACK_TRACE_PERMISSION);}// optimization so we do not call into the vm for threads that// have not yet started or have terminatedif (!isAlive()) {return EMPTY_STACK_TRACE;}StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this});StackTraceElement[] stackTrace = stackTraceArray[0];// a thread that was alive during the previous isAlive call may have// since terminated, therefore not having a stacktrace.if (stackTrace == null) {stackTrace = EMPTY_STACK_TRACE;}return stackTrace;} else {// Don't need JVM help for current threadreturn (new Exception()).getStackTrace();}}

在if語句里面因為 ??this != Thread.currentThread()是為true的,所以方法會執行else里面的語句

return (new Exception()).getStackTrace();

new Exception().getStackTrace();就是這句話讓使用Thread的getStackTrace方法就有可能多打印一句java.lang.Thread;getStackTrace;Thread.java ? ? ?

這也就是為什么使用

logger = LoggerFactory.getLogger(Thread.currentThread().getStackTrace()[1].getClassName());

會得不到正確的日志信息的原因了!

應該就是這樣子了,為了驗證我想的對不對,寫了一個測試驗證的例子,代碼如下:

public class TestException {public static StackTraceElement[] getStackTrace() {return new Exception().getStackTrace();} } public class ThreadTest {public static void TestString(){StackTraceElement[] arr = TestException.getStackTrace();for(int i=0;i<=arr.length-1;i++){System.out.println(arr[i].getClassName()+";"+arr[i].getMethodName()+";"+arr[i].getFileName());}} } public class App {public static void main( String[] args ){ThreadTest.TestString();} }

執行之后的結果是:

test.TestException;getStackTrace;TestException.java

test.ThreadTest;TestString;ThreadTest.java

test.App;main;App.java

解決辦法很簡單,

要么使用new Exception().getStackTrace()[1];

要么使用Thread.currentThread().getStackTrace()[2]。





總結

以上是生活随笔為你收集整理的得到当前堆栈信息的两种方式(Thread和Throwable)的方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。