Getting the name of the currently executing method

JavaReflectionMethods

Java Problem Overview


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

Java Solutions


Solution 1 - Java

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.

Solution 2 - Java

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Thread.html">Thread</a>.<a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Thread.html#currentThread()">currentThread()</a>.<a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Thread.html#getStackTrace()">getStackTrace()</a></code> will usually contain the method you’re calling it from but there are pitfalls (see Javadoc):

> Some virtual machines may, under some circumstances, omit one or more stack frames from the stack trace. In the extreme case, a virtual machine that has no stack trace information concerning this thread is permitted to return a zero-length array from this method.

Solution 3 - Java

January 2009:
A full code would be (to use with @Bombe's caveat in mind):

/**
 * Get the method name for a depth in call stack. <br />
 * Utility function
 * @param depth depth in the call stack (0 means current method, 1 means call method, ...)
 * @return method name
 */
public static String getMethodName(final int depth)
{
  final StackTraceElement[] ste = Thread.currentThread().getStackTrace();

  //System. out.println(ste[ste.length-depth].getClassName()+"#"+ste[ste.length-depth].getMethodName());
  // return ste[ste.length - depth].getMethodName();  //Wrong, fails for depth = 0
  return ste[ste.length - 1 - depth].getMethodName(); //Thank you Tom Tresansky
}

More in this question.

Update December 2011:

bluish comments:

> I use JRE 6 and gives me incorrect method name.
It works if I write ste[2 + depth].getMethodName().

> - 0 is getStackTrace(),

  • 1 is getMethodName(int depth) and
  • 2 is invoking method.

virgo47's answer (upvoted) actually computes the right index to apply in order to get back the method name.

Solution 4 - Java

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. :-)

Solution 5 - Java

 public class SomeClass {
   public void foo(){
      class Local {};
      String name = Local.class.getEnclosingMethod().getName();
   }
 }

name will have value foo.

Solution 6 - Java

Both of these options work for me with Java:

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

Or:

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

Solution 7 - Java

The fastest way I found is that:

import java.lang.reflect.Method;

public class TraceHelper {
	// save it static to have it available on every call
	private static Method m;

	static {
		try {
			m = Throwable.class.getDeclaredMethod("getStackTraceElement",
					int.class);
			m.setAccessible(true);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String getMethodName(final int depth) {
		try {
			StackTraceElement element = (StackTraceElement) m.invoke(
					new Throwable(), depth + 1);
			return element.getMethodName();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}

It accesses the native method getStackTraceElement(int depth) directly. And stores the accessible Method in a static variable.

Solution 8 - Java

Use the following Code :

	StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
	StackTraceElement e = stacktrace[1];//coz 0th will be getStackTrace so 1st
	String methodName = e.getMethodName();
	System.out.println(methodName);

Solution 9 - Java

This can be done using StackWalker since Java 9.

public static String getCurrentMethodName() {
    return StackWalker.getInstance()
                      .walk(s -> s.skip(1).findFirst())
                      .get()
                      .getMethodName();
}

public static String getCallerMethodName() {
    return StackWalker.getInstance()
                      .walk(s -> s.skip(2).findFirst())
                      .get()
                      .getMethodName();
}

StackWalker is designed to be lazy, so it's likely to be more efficient than, say, Thread.getStackTrace which eagerly creates an array for the entire callstack. Also see the JEP for more information.

Solution 10 - Java

public static String getCurrentMethodName() {
		return Thread.currentThread().getStackTrace()[2].getClassName() + "." + Thread.currentThread().getStackTrace()[2].getMethodName();
	}

Solution 11 - Java

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 + ")";
    }
}

Solution 12 - Java

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

Solution 13 - Java

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
    }
}

Solution 14 - Java

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()][1] (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());

[1]: http://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html#getStackTrace%28%29 "Throwable.getStackTrace()"

Solution 15 - Java

String methodName =Thread.currentThread().getStackTrace()[1].getMethodName();
System.out.println("methodName = " + methodName);

Solution 16 - Java

I've got solution using this (In Android)

/**
 * @param className       fully qualified className
 *                        <br/>
 *                        <code>YourClassName.class.getName();</code>
 *                        <br/><br/>
 * @param classSimpleName simpleClassName
 *                        <br/>
 *                        <code>YourClassName.class.getSimpleName();</code>
 *                        <br/><br/>
 */
public static void getStackTrace(final String className, final String classSimpleName) {
    final StackTraceElement[] steArray = Thread.currentThread().getStackTrace();
    int index = 0;
    for (StackTraceElement ste : steArray) {
        if (ste.getClassName().equals(className)) {
            break;
        }
        index++;
    }
    if (index >= steArray.length) {
        // Little Hacky
        Log.w(classSimpleName, Arrays.toString(new String[]{steArray[3].getMethodName(), String.valueOf(steArray[3].getLineNumber())}));
    } else {
        // Legitimate
        Log.w(classSimpleName, Arrays.toString(new String[]{steArray[index].getMethodName(), String.valueOf(steArray[index].getLineNumber())}));
    }
}

Solution 17 - Java

I don't know what is the intention behind getting the currently executed method's name, but if that's just for debugging purpose, then logging frameworks like "logback" can help here. For example, in logback, all you need to do is to use the pattern "%M" in your logging configuration. However, this should be used with caution as this may degrade performance.

Solution 18 - Java

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

Solution 19 - Java

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

Solution 20 - Java

I use this code snippet with the latest Android Studio with the latest Java update. It can be called from any Activity, Fragment, etc.

public static void logPoint() {
    String[] splitPath = Thread.currentThread().getStackTrace()[3]
        .toString().split("\\.");

    Log.d("my-log", MessageFormat.format("{0} {1}.{2}",
        splitPath[splitPath.length - 3],
        splitPath[splitPath.length - 2],
        splitPath[splitPath.length - 1]
    ));
}

call it like this

logPoint();

output

... D/my-log: MainActivity onCreate[(MainActivity.java:44)]

Solution 21 - Java

I rewritten a little the maklemenz's answer:

private static Method m;

static {
    try {
        m = Throwable.class.getDeclaredMethod(
            "getStackTraceElement",
            int.class
        );
    }
    catch (final NoSuchMethodException e) {
        throw new NoSuchMethodUncheckedException(e);
    }
    catch (final SecurityException e) {
        throw new SecurityUncheckedException(e);
    }
}


public static String getMethodName(int depth) {
    StackTraceElement element;
    
    final boolean accessible = m.isAccessible();
    m.setAccessible(true);
    
    try {
        element = (StackTraceElement) m.invoke(new Throwable(), 1 + depth);
    }
    catch (final IllegalAccessException e) {
        throw new IllegalAccessUncheckedException(e);
    }
    catch (final InvocationTargetException e) {
        throw new InvocationTargetUncheckedException(e);
    }
    finally {
        m.setAccessible(accessible);
    }
    
    return element.getMethodName();
}

public static String getMethodName() {
    return getMethodName(1);
}

Solution 22 - Java

MethodHandles.lookup().lookupClass().getEnclosingMethod().getName();

Solution 23 - Java

What's wrong with this approach:

class Example {
    FileOutputStream fileOutputStream;

    public Example() {
        //System.out.println("Example.Example()");
             
        debug("Example.Example()",false); // toggle

        try {
            fileOutputStream = new FileOutputStream("debug.txt");
        } catch (Exception exception) {
             debug(exception + Calendar.getInstance().getTime());
        }
    }

    private boolean was911AnInsideJob() {
        System.out.println("Example.was911AnInsideJob()");
        return true;
    }

    public boolean shouldGWBushBeImpeached(){
        System.out.println("Example.shouldGWBushBeImpeached()");
        return true;
    }

    public void setPunishment(int yearsInJail){
        debug("Server.setPunishment(int yearsInJail=" + yearsInJail + ")",true);
    }
}

And before people go crazy about using System.out.println(...) you could always, and should, create some method so that output can be redirected, e.g:

    private void debug (Object object) {
        debug(object,true);
    }

    private void dedub(Object object, boolean debug) {
        if (debug) {
            System.out.println(object);

            // you can also write to a file but make sure the output stream
            // ISN'T opened every time debug(Object object) is called

            fileOutputStream.write(object.toString().getBytes());
        }
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOmar KoohejiView Question on Stackoverflow
Solution 1 - JavaDevinView Answer on Stackoverflow
Solution 2 - JavaBombeView Answer on Stackoverflow
Solution 3 - JavaVonCView Answer on Stackoverflow
Solution 4 - Javavirgo47View Answer on Stackoverflow
Solution 5 - JavaalexsmailView Answer on Stackoverflow
Solution 6 - JavaCharlie SeligmanView Answer on Stackoverflow
Solution 7 - Javauser1563700View Answer on Stackoverflow
Solution 8 - JavaSumit SinghView Answer on Stackoverflow
Solution 9 - JavaRadiodefView Answer on Stackoverflow
Solution 10 - JavaJayView Answer on Stackoverflow
Solution 11 - JavamvanleView Answer on Stackoverflow
Solution 12 - JavaFriso van der MadeView Answer on Stackoverflow
Solution 13 - JavaMaxpleView Answer on Stackoverflow
Solution 14 - JavaJoolView Answer on Stackoverflow
Solution 15 - JavaranView Answer on Stackoverflow
Solution 16 - JavaKasim RangwalaView Answer on Stackoverflow
Solution 17 - JavaJames SelvakumarView Answer on Stackoverflow
Solution 18 - JavaEglView Answer on Stackoverflow
Solution 19 - JavamjsView Answer on Stackoverflow
Solution 20 - JavafixView Answer on Stackoverflow
Solution 21 - JavaMarco SullaView Answer on Stackoverflow
Solution 22 - JavaDarrenView Answer on Stackoverflow
Solution 23 - JavajohnnyView Answer on Stackoverflow