首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 獲取當前方法名與類名的兩種標準姿勢

     編輯:Java 相關知識

場景:日誌埋點、AOP 切面、異常鏈路追蹤

C/C++ 有 __func__,Java 無關鍵字,需通過運行時棧獲取。

方式一:Thread.currentThread().getStackTrace()

public class Demo {
    public void test() {
        StackTraceElement[] stack = Thread.currentThread().getStackTrace();
        // stack[0] = getStackTrace()
        // stack[1] = test()  ← 當前方法
        // stack[2] = 調用者
        System.out.println("方法名: " + stack[1].getMethodName());
        System.out.println("類名: " + stack[1].getClassName());
        System.out.println("行號: " + stack[1].getLineNumber());
    }
}
  • 優點:不拋出異常,性能相對較好;
  • 索引位置:[1] 為當前方法(JDK 8+ 穩定)。

方式二:new Throwable().getStackTrace()

public class Demo {
    public void test() {
        StackTraceElement[] stack = new Throwable().getStackTrace();
        // stack[0] = test()  ← 當前方法
        System.out.println("方法名: " + stack[0].getMethodName());
        System.out.println("類名: " + stack[0].getClassName());
    }
}
  • 優點:語義直觀,「拋出異常即捕獲棧」;
  • 索引位置:[0] 為當前方法;
  • 缺點:創建 Throwable 對象開銷略大,高頻調用慎用。

索引不穩定?JDK 版本差異實測

建議:單元測試驗證一次後硬編碼索引,或封裝工具類自動檢測:

public class StackUtil {
    private static final int CURRENT_METHOD_INDEX_THREAD = detectThreadIndex();
    private static final int CURRENT_METHOD_INDEX_THROWABLE = 0; // 固定

    private static int detectThreadIndex() {
        StackTraceElement[] stack = Thread.currentThread().getStackTrace();
        for (int i = 0; i < stack.length; i++) {
            if ("detectThreadIndex".equals(stack[i].getMethodName())) return i + 1;
        }
        return 1; // fallback
    }

    public static String getCurrentMethodName() {
        return Thread.currentThread().getStackTrace()[CURRENT_METHOD_INDEX_THREAD].getMethodName();
    }
}

性能對比 (100萬次調用)

  • Thread.getStackTrace():~45 ms
  • new Throwable().getStackTrace():~120 ms

高頻場景(如每請求日誌)首選 Thread 方式;低頻場景(異常處理、啟動掃描)Throwable 更語義化。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
JDK 版本Thread.getStackTrace() 當前方法索引Throwable.getStackTrace() 當前方法索引
JDK 810
JDK 1110
JDK 1710