Getting the name of the currently executing method

2018-12-31 06:26发布

Is there a way to get the name of the currently executing method in Java?

20条回答
泛滥B
2楼-- · 2018-12-31 07:05

To get the name of the method that called the current method you can use:

new Exception("is not thrown").getStackTrace()[1].getMethodName()

This works on my MacBook as well as on my Android phone

I also tried:

Thread.currentThread().getStackTrace()[1]

but Android will return "getStackTrace" I could fix this for Android with

Thread.currentThread().getStackTrace()[2]

but then I get the wrong answer on my MacBook

查看更多
与君花间醉酒
3楼-- · 2018-12-31 07:06
String methodName =Thread.currentThread().getStackTrace()[1].getMethodName();
System.out.println("methodName = " + methodName);
查看更多
妖精总统
4楼-- · 2018-12-31 07:08

Both of these options work for me with Java:

new Object(){}.getClass().getEnclosingMethod().getName()

Or:

Thread.currentThread().getStackTrace()[1].getMethodName()
查看更多
路过你的时光
5楼-- · 2018-12-31 07:10

Technically this will work...

String name = new Object(){}.getClass().getEnclosingMethod().getName();

However, a new anonymous inner class will be created during compile time (e.g. YourClass$1.class). So this will create a .class file for each method that deploys this trick. Additionally an otherwise unused object instance is created on each invocation during runtime. So this may be an acceptable debug trick, but it does come with significant overhead.

An advantage of this trick is that getEncosingMethod() returns java.lang.reflect.Method which can be used to retrieve all other information of the method including annotations and parameter names. This makes it possible to distinguish between specific methods with the same name (method overload).

Note that according to the JavaDoc of getEnclosingMethod() this trick should not throw a SecurityException as inner classes should be loaded using the same class loader. So there is no need to check the access conditions even if a security manager is present.

It is required to use getEnclosingConstructor() for constructors. During blocks outside of (named) methods, getEnclosingMethod() returns null.

查看更多
高级女魔头
6楼-- · 2018-12-31 07:12

An alternative method is to create, but not throw, an Exception, and use that object from which to get the stack trace data, since the enclosing method will typically be at index 0 - as long as the JVM stores that information, as others have mentioned above. This not the cheapest method, however.

From Throwable.getStackTrace() (this has been the same since Java 5 at least):

The zeroth element of the array (assuming the array's length is non-zero) represents the top of the stack, which is the last method invocation in the sequence. Typically, this is the point at which this throwable was created and thrown.

The snippet below assumes the class is non-static (because of getClass()), but that's an aside.

System.out.printf("Class %s.%s\n", getClass().getName(), new Exception("is not thrown").getStackTrace()[0].getMethodName());
查看更多
余生请多指教
7楼-- · 2018-12-31 07:14

We used this code to mitigate potential variability in stack trace index - now just call methodName util:

public class MethodNameTest {
    private static final int CLIENT_CODE_STACK_INDEX;

    static {
        // Finds out the index of "this code" in the returned stack trace - funny but it differs in JDK 1.5 and 1.6
        int i = 0;
        for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
            i++;
            if (ste.getClassName().equals(MethodNameTest.class.getName())) {
                break;
            }
        }
        CLIENT_CODE_STACK_INDEX = i;
    }

    public static void main(String[] args) {
        System.out.println("methodName() = " + methodName());
        System.out.println("CLIENT_CODE_STACK_INDEX = " + CLIENT_CODE_STACK_INDEX);
    }

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

Seems overengineered, but we had some fixed number for JDK 1.5 and were a bit surprised it changed when we moved to JDK 1.6. Now it's the same in Java 6/7, but you just never know. It is not proof to changes in that index during runtime - but hopefully HotSpot doesn't do that bad. :-)

查看更多
登录 后发表回答