在 JAVA 程序有時需要獲取當前代碼位置, 於是就利用 Thread.currentThread().getStackTrace() 寫了下面這個工具類, 用來獲取當前執行位置處代碼的文件名/類名/方法名/行號.
當然通過 new Throwable().getStackTrace() 也能得到同樣信息, 在處理異常時用這種方法還行, 否則需要 new 一個 Throwable, 感覺有點浪費😄
至於為什么 CurrentLineInfo.originStackIndex 的值是 2 呢? 這是因為通過自定義的靜態方法調用 Thread.currentThread().getStackTrace() 獲取當前函數棧時, 已多加了兩層方法調用.
比如說在 Main.main() 方法中獲取當前行號時, 其調用鏈為:
Main.main() --> CurrentLineInfo.getLineNumber() --> Thread.getStackStrace()
因為棧是 先入后出 (隊列是 先入先出), 所以最初調用位置的函數棧下表是 2.
這一點在調試時也可以看到:

下面是源碼和測試:
CurrentLineInfo.java:
package com.example.lineno;
public class CurrentLineInfo {
private static int originStackIndex = 2;
public static String getFileName() {
return Thread.currentThread().getStackTrace()[originStackIndex].getFileName();
}
public static String getClassName() {
return Thread.currentThread().getStackTrace()[originStackIndex].getClassName();
}
public static String getMethodName() {
return Thread.currentThread().getStackTrace()[originStackIndex].getMethodName();
}
public static int getLineNumber() {
return Thread.currentThread().getStackTrace()[originStackIndex].getLineNumber();
}
}
測試代碼 Main.java:
package com.example.lineno;
public class Main {
public static void main(String[] args) {
System.out.println(CurrentLineInfo.getFileName());
System.out.println(CurrentLineInfo.getClassName());
System.out.println(CurrentLineInfo.getMethodName());
System.out.println(CurrentLineInfo.getLineNumber());
}
}
測試輸出:
FileName: Main.java
ClassName: com.example.lineno.Main
MethodName: main
LineNumber: 8
