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

Java 獲取原始碼檔案名與行號:StackTraceElement 實戰

     編輯:Java 相關知識

背景:C/C++ 的 __FILE__、__LINE__ 宏

// C 範例
#include 
int main() {
    fprintf(stdout, "[%s:%d] Hello World!", __FILE__, __LINE__);
    return 0;
}
// 輸出: [main.c:4] Hello World!

Java 無預處理器宏,但提供 java.lang.StackTraceElement 類在運行時獲取堆棧幀資訊。

兩種獲取途徑

封裝工具類


public class SourceLocation {
    // 堆棧索引說明:
    // [0] = getStackTrace() 呼叫點
    // [1] = getLineNumber()/getFileName() 所在方法
    // [2] = 呼叫此工具方法的「調用者」 ← 我們想要的
    private static final int CALLER_DEPTH = 2;

    public static int getLineNumber() {
        return Thread.currentThread().getStackTrace()[CALLER_DEPTH].getLineNumber();
    }

    public static String getFileName() {
        return Thread.currentThread().getStackTrace()[CALLER_DEPTH].getFileName();
    }

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

    public static String getClassName() {
        return Thread.currentThread().getStackTrace()[CALLER_DEPTH].getClassName();
    }

    // 格式化輸出範例
    public static void printLocation(String msg) {
        StackTraceElement ste = Thread.currentThread().getStackTrace()[CALLER_DEPTH];
        System.out.printf("[%s:%d %s] %s%n",
            ste.getFileName(), ste.getLineNumber(), ste.getMethodName(), msg);
    }
}

測試驗證


public class LineNoTest {
    public static void main(String[] args) {
        SourceLocation.printLocation("Hello World!");
        // 輸出範例: [LineNoTest.java:10 main] Hello World!
    }
}

魔法數字 2 的含義

getStackTrace() 返回陣列索引對應:

  1. 0:Thread.getStackTrace() 內部本機方法調用點。
  2. 1:SourceLocation.getLineNumber() 方法調用點。
  3. 2:呼叫 SourceLocation.getLineNumber() 的那一行代碼(即業務調用處)。

若工具方法再被封裝一層,深度需相應增加(如 3)。建議封裝為 getCaller(int depth) 靈活指定。

效能與替代方案

  • getStackTrace() 較重(捕獲完整堆棧),高頻日誌建議用 new Throwable().getStackTrace() 或 Java 9+ StackWalker API(延遲、可篩選、支援隱藏框架幀)。
  • Log4j2、SLF4J 等成熟日誌框架已內建高效位置資訊獲取,業務代碼宜直接使用框架提供的 %F:%L 模式。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
途徑代碼示例適用場景
Thread.currentThread().getStackTrace()當前線程完整堆棧快照通用工具方法、日誌框架
new Throwable().getStackTrace()拋出點堆棧(不實際拋出)輕量級,避免創建完整線程堆棧