跳到主內容

【反射】java 如何取得目前程式碼所在的 function name

 

public class MyClass {
    public static void main(String[] args) {
        String methodName = new Object() {}
            .getClass()
            .getEnclosingMethod()
            .getName();
        
        System.out.println("目前所在的方法名稱為:" + methodName);
    }
}

這段程式碼使用了匿名內部類別的方式來取得目前所在的方法名稱。在這個匿名內部類別中,呼叫 getClass() 方法可以取得目前物件的類別,接著呼叫 getEnclosingMethod() 方法可以取得該物件所在的方法,最後呼叫 getName() 方法可以取得該方法的名稱。

需要注意的是,由於這個方法使用了匿名內部類別,所以每次呼叫都會產生一個新的物件,可能會對效能造成一些影響。


如果 getEnclosingMethod() 方法回傳 null,表示目前的程式碼不是定義在一個方法裡面,而是定義在類別的初始化區塊(initializer block)或建構子(constructor)中,或者是在類別的靜態初始化區塊(static initializer block)或靜態建構子(static constructor)中。

在這種情況下,可以使用 Thread.currentThread().getStackTrace() 方法來取得當前執行緒的呼叫堆疊(call stack),然後從呼叫堆疊中找到第一個方法的名稱,這個方法的名稱就是目前所在的方法名稱。

以下是一個示範程式碼,可以在這種情況下取得目前所在的方法名稱:

public class MyClass {
    public MyClass() {
        String methodName = getMethodName();
        System.out.println("目前所在的方法名稱為:" + methodName);
    }

    static {
        String methodName = getMethodName();
        System.out.println("目前所在的方法名稱為:" + methodName);
    }

    {
        String methodName = getMethodName();
        System.out.println("目前所在的方法名稱為:" + methodName);
    }

    public static void main(String[] args) {
        String methodName = getMethodName();
        System.out.println("目前所在的方法名稱為:" + methodName);
    }

    private static String getMethodName() {
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        for (StackTraceElement stackTraceElement : stackTrace) {
            String methodName = stackTraceElement.getMethodName();
            if (!methodName.equals("getStackTrace") &&
                !methodName.equals("getMethodName") &&
                !methodName.equals("main")) {
                return methodName;
            }
        }
        return null;
    }
}

這個程式碼定義了幾個方法和初始化區塊,在每個區塊中都呼叫了 getMethodName() 方法來取得目前所在的方法名稱。在 getMethodName() 方法中,首先取得目前執行緒的呼叫堆疊,然後從呼叫堆疊中找到第一個不是 getStackTrace()getMethodName()main() 的方法名稱,這個方法的名稱就是目前所在的方法名稱。