Throwable.getStackTrace() 返回 StackTraceElement[],索引 0 為當前方法,1 為調用者。
public class StackTraceUtil {
private static StackTraceElement caller() {
return new Throwable().getStackTrace()[1];
}
public static int getLineNumber() { return caller().getLineNumber(); }
public static String getMethodName() { return caller().getMethodName(); }
public static String getFileName() { return caller().getFileName(); }
public static String getClassName() { return caller().getClassName(); }
// 組合信息
public static String getLocation() {
StackTraceElement e = caller();
return e.getFileName() + ":" + e.getLineNumber() + " " + e.getClassName() + "." + e.getMethodName();
}
}
public class Demo {
public static void main(String[] args) {
foo();
}
static void foo() { bar(); }
static void bar() {
System.out.println(StackTraceUtil.getLocation());
// 輸出: Demo.java:10 Demo.bar
}
}
創建 Throwable 並獲取堆棧較重,高頻調用建議緩存或使用 Java 9 StackWalker (支持懶加載、過濾)。
public static String getLocationModern() {
return StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
.walk(s -> s.skip(1).findFirst()
.map(f -> f.getFileName() + ":" + f.getLineNumber() + " " + f.getClassName() + "." + f.getMethodName())
.orElse("unknown"));
}