Getting the name of the currently executing method

前端 未结 22 2245
闹比i
闹比i 2020-11-22 03:33

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

相关标签:
22条回答
  • 2020-11-22 04:17

    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 getEnclosingMethod() 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.

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

    0 讨论(0)
  • 2020-11-22 04:17

    This is an expansion on virgo47's answer (above).

    It provides some static methods to get the current and invoking class / method names.

    /* Utility class: Getting the name of the current executing method 
     * https://stackoverflow.com/questions/442747/getting-the-name-of-the-current-executing-method
     * 
     * Provides: 
     * 
     *      getCurrentClassName()
     *      getCurrentMethodName()
     *      getCurrentFileName()
     * 
     *      getInvokingClassName()
     *      getInvokingMethodName()
     *      getInvokingFileName()
     *
     * Nb. Using StackTrace's to get this info is expensive. There are more optimised ways to obtain
     * method names. See other stackoverflow posts eg. https://stackoverflow.com/questions/421280/in-java-how-do-i-find-the-caller-of-a-method-using-stacktrace-or-reflection/2924426#2924426
     *
     * 29/09/2012 (lem) - added methods to return (1) fully qualified names and (2) invoking class/method names
     */
    package com.stackoverflow.util;
    
    public class StackTraceInfo
    {
        /* (Lifted from virgo47's stackoverflow answer) */
        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(StackTraceInfo.class.getName()))
                {
                    break;
                }
            }
            CLIENT_CODE_STACK_INDEX = i;
        }
    
        public static String getCurrentMethodName()
        {
            return getCurrentMethodName(1);     // making additional overloaded method call requires +1 offset
        }
    
        private static String getCurrentMethodName(int offset)
        {
            return Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX + offset].getMethodName();
        }
    
        public static String getCurrentClassName()
        {
            return getCurrentClassName(1);      // making additional overloaded method call requires +1 offset
        }
    
        private static String getCurrentClassName(int offset)
        {
        return Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX + offset].getClassName();
        }
    
        public static String getCurrentFileName()
        {
            return getCurrentFileName(1);     // making additional overloaded method call requires +1 offset
        }
    
        private static String getCurrentFileName(int offset)
        {
            String filename = Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX + offset].getFileName();
            int lineNumber = Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX + offset].getLineNumber();
    
            return filename + ":" + lineNumber;
        }
    
        public static String getInvokingMethodName()
        {
            return getInvokingMethodName(2); 
        }
    
        private static String getInvokingMethodName(int offset)
        {
            return getCurrentMethodName(offset + 1);    // re-uses getCurrentMethodName() with desired index
        }
    
        public static String getInvokingClassName()
        {
            return getInvokingClassName(2); 
        }
    
        private static String getInvokingClassName(int offset)
        {
            return getCurrentClassName(offset + 1);     // re-uses getCurrentClassName() with desired index
        }
    
        public static String getInvokingFileName()
        {
            return getInvokingFileName(2); 
        }
    
        private static String getInvokingFileName(int offset)
        {
            return getCurrentFileName(offset + 1);     // re-uses getCurrentFileName() with desired index
        }
    
        public static String getCurrentMethodNameFqn()
        {
            return getCurrentMethodNameFqn(1);
        }
    
        private static String getCurrentMethodNameFqn(int offset)
        {
            String currentClassName = getCurrentClassName(offset + 1);
            String currentMethodName = getCurrentMethodName(offset + 1);
    
            return currentClassName + "." + currentMethodName ;
        }
    
        public static String getCurrentFileNameFqn()
        {
            String CurrentMethodNameFqn = getCurrentMethodNameFqn(1);
            String currentFileName = getCurrentFileName(1);
    
            return CurrentMethodNameFqn + "(" + currentFileName + ")";
        }
    
        public static String getInvokingMethodNameFqn()
        {
            return getInvokingMethodNameFqn(2);
        }
    
        private static String getInvokingMethodNameFqn(int offset)
        {
            String invokingClassName = getInvokingClassName(offset + 1);
            String invokingMethodName = getInvokingMethodName(offset + 1);
    
            return invokingClassName + "." + invokingMethodName;
        }
    
        public static String getInvokingFileNameFqn()
        {
            String invokingMethodNameFqn = getInvokingMethodNameFqn(2);
            String invokingFileName = getInvokingFileName(2);
    
            return invokingMethodNameFqn + "(" + invokingFileName + ")";
        }
    }
    
    0 讨论(0)
  • 2020-11-22 04:19

    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

    0 讨论(0)
  • 2020-11-22 04:24

    Just in case the method which name you want to know is a junit test method, then you can use junit TestName rule: https://stackoverflow.com/a/1426730/3076107

    0 讨论(0)
  • 2020-11-22 04:25

    Util.java:

    public static String getCurrentClassAndMethodNames() {
        final StackTraceElement e = Thread.currentThread().getStackTrace()[2];
        final String s = e.getClassName();
        return s.substring(s.lastIndexOf('.') + 1, s.length()) + "." + e.getMethodName();
    }
    

    SomeClass.java:

    public class SomeClass {
        public static void main(String[] args) {
            System.out.println(Util.getCurrentClassAndMethodNames()); // output: SomeClass.main
        }
    }
    
    0 讨论(0)
  • 2020-11-22 04:25

    Most answers here seems wrong.

        public static String getCurrentMethod() {
                return getCurrentMethod(1);
        }
        public static String getCurrentMethod(int skip) {
                return Thread.currentThread().getStackTrace()[1 + 1 + skip].getMethodName();
        }
    

    Example:

        public static void main(String[] args) {
                aaa();
        }
    
        public static void aaa() {
                System.out.println("aaa  -> "  + getCurrentMethod( ) );
                System.out.println("aaa  -> "  + getCurrentMethod(0) );
                System.out.println("main -> "  + getCurrentMethod(1) );
        }
    

    Outputs:

    aaa  -> aaa
    aaa  -> aaa
    main -> main
    
    0 讨论(0)
提交回复
热议问题