By Omar Kooheji


2009-01-14 12:20:39 8 Comments

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

22 comments

@mmm 2020-03-29 15:50:23

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

@AmerllicA 2020-05-05 19:08:52

Thanks for your useful answer.

@Xobotun 2020-05-06 14:35:44

Could you please clarify why do most answer seem wrong for you? There are many answers and I'm not that well-versed in Java to read all of them and to understand what's the difference between them and your answer. :(

@Xobotun 2020-05-10 16:18:28

@mmm Sorry, but I strongly disagree. I come here to learn and so do many others, I believe. I just cannot understand why do you think I don't deserve to know more on this subject. I want to make less mistakes in my code and to warn others, not to follow some cargo-cult. You could've at least clarified what Java version this code should be correct on. :( An answer below says there was a change in stacktrace between 1.5 and 1.6. Maybe you imply there's something like that in the upcoming Java 14, how can I know. Or different vendor may have. Sorry if I misinterpreted your answer as a rude one.

@Marco Sulla 2019-09-20 18:30:19

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

@Bombe 2009-01-14 12:29:03

Thread.currentThread().getStackTrace() 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.

@Nate Parsons 2009-03-03 19:15:49

Is this same pitfall true for stack traces in exceptions?

@Bombe 2011-11-11 16:50:09

Yes, it is. The documentation for Throwable.[getStackTrace()](download.oracle.com/javase/1.5.0‌​/docs/api/java/lang/‌​… contains the exact same paragraph.

@Thorbjørn Ravn Andersen 2013-04-15 08:53:31

The underlying thing is that the JVM is not required to be able to provide a stacktrace, but that a lot of work has gone into making HotSpot very reliable. You need to know, though, in case you want your code to not rely on the behavior of a specific JVM.

@Gus 2013-07-06 21:48:31

Alexsmail's version below does not create a stack trace and gives you access to the actual method object, not just the name (so you can find out return type too). I haven't bench marked but I suspect his method is much faster too since stack traces tend to be expensive.

@risingTide 2016-02-03 15:46:21

Devin's response seems to give a much more succinct answer to this question.

@Radiodef 2018-09-14 15:45:13

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.

@Egl 2018-02-20 14:08:44

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

@EJoshuaS - Reinstate Monica 2019-05-27 23:22:26

@AndreiKonstantinov I don't think that this is link-only. Even if you remove the link, there's still at least some information to go on.

@James Selvakumar 2016-11-08 02:04:26

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.

@Darren 2016-09-27 10:20:09

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

@abarisone 2016-09-27 14:31:17

Please edit with more information. Code-only and "try this" answers are discouraged, because they contain no searchable content, and don't explain why someone should "try this".

@Toby Speight 2016-09-28 08:27:47

Although this code may help to solve the problem, it doesn't explain why and/or how it answers the question. Providing this additional context would significantly improve its long-term educational value. Please edit your answer to add explanation, including what limitations and assumptions apply.

@Benj 2016-10-11 12:29:24

Only for Java 7+, but concise way to get the method name. Still, remains the performance considerations of such a call.

@Markus L 2017-04-07 09:47:23

getEnclosingMethod() throws a NullPointerException for me in Java 7.

@stove 2018-04-25 07:21:07

The java.lang.Class.getEnclosingMethod() returns a Method object representing the immediately enclosing method of the underlying class, if this Class object represents a local or anonymous class within a method, else returns null.

@Benj 2018-07-27 13:35:35

What is the footprint of such a call ?

@Radiodef 2018-09-14 15:57:31

This answer isn't correct. lookup().lookupClass() returns the class of the current method, and getEnclosingMethod() returns the method which the current class is declared in, if the current class is a local class. See ideone.com/jfN5GW. In other words, given void foo() { class Local { void bar() { System.out.println(lookup().lookupClass().getEnclosingMethod‌​()); } } new Local().bar(); }, the method foo() is printed (because it's the enclosing method of Local), but this question wants the method bar() (because it's the "currently executing" method).

@Kasim Rangwala 2016-03-03 06:53:00

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())}));
    }
}

@Maxple 2015-11-02 08:21:09

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

@Marks 2015-11-26 12:05:20

final StackTraceElement e = Thread.currentThread().getStackTrace()[2]; works; e.getClassName(); return the full class name and e.getMethodName() return the methon name.

@PhilLab 2017-07-13 16:59:51

getStackTrace()[2] is wrong, it has to be getStackTrace()[3] because: [0] dalvik.system.VMStack.getThreadStackTrace [1] java.lang.Thread.getStackTrace [2] Utils.getCurrentClassAndMethodNames [3] The function a() calling this one

@Friso van der Made 2015-09-22 10:39:30

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

@mbm29414 2016-03-21 15:23:34

In recent testing on Android, it worked better for me to use getStackTrace()[0] rather than getStackTrace()[1]. YMMV.

@Ninja 2017-10-17 11:05:36

up for android is Thread.currentThread().getStackTrace()[2]

@Charlie Seligman 2015-09-01 10:21:59

Both of these options work for me with Java:

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

Or:

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

@jellobird 2017-05-31 10:21:24

for static methods use: <Class>.class.getEnclosingMethod().getName()

@el-teedee 2018-02-28 14:29:02

be carefull of empty array according to Bombe's answer and javadoc indication. Some JVM may not fill the stacktrace array?

@johnny 2014-08-25 05:03:24

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());
        }
    }

@ivarni 2014-08-25 05:48:51

@Saksham it looks to me like that was actually an attempt to answer the question. Not a great attempt, but an attempt none the less.

@johnny 2014-08-25 06:31:46

@ivarni "not a good attempt"? whats wrong with it? are you familiar with the "kiss principle"?

@johnny 2014-08-25 06:33:15

@Saksham it was rhetorical.

@ivarni 2014-08-25 06:37:00

@johnny In the codebase I have in front of me right now there are 271 classes. Even with a (low estimate) og 5 methods per class that's over 1300 methods. And this is not even a big codebase. You don't see the problem with scaling up your approach? I'm quite happy to agree to disagree, but that's why I said it's not a good attempt. It introduces a massive amount of overhead in any non-trivial codebase.

@johnny 2014-08-25 06:42:31

@ivarni wouldnt you have to include a method call in each method (as suggested above) to perform the same and LESS reliable functon?

@ivarni 2014-08-25 06:45:17

@johnny Not if you use an aspect.

@Just another metaprogrammer 2014-08-25 14:00:52

In my opinion the main problem is that I would be repeating myself. This hurts maintainability. Now I am not a fan of the stacktrace, local class or exception tricks as they affect performance negatively and are sometimes unreliable for something the compiler knows very well at compile-time. I personally came here looking for something like __func__ but I suspect we end up with Johnnys approach as it seems the least bad.

@johnny 2014-08-25 15:22:32

@FuleSnabel "hurts maintainablity"? youre talking about one line of code per method, it always gets called, you always know where you are and you dont need 3rd party utlities. i dont understand why people seem to think its a major problem. its also great for parameter checking as well.

@Just another metaprogrammer 2014-08-26 10:59:47

@johnny I guess I have seen too many cases where the method name doesn't match the string which have sent me in the wrong direction when debugging. But in Java I still think your suggestion is the best, the other alternatives "cost" too much.

@Jool 2014-12-15 11:48:42

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());

@Devin 2011-05-05 00:20:50

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.

@Drupad Panchal 2011-12-13 16:00:36

Please comment if this is supported across all JVMs and that no such limitation similar to the omission of Stacktrace, exists

@shrini1000 2012-05-04 10:52:43

This won't give you currently executing method. This will give you that method in which an anonymous/local class is defined. - docs.oracle.com/javase/6/docs/api/java/lang/…

@alexsmail 2013-03-13 05:16:45

class Local {}; String name = Local.class.getEnclosingMethod().getName();

@Thorbjørn Ravn Andersen 2013-04-15 08:54:42

@shrini1000 the idea is to use this snippet where the information is needed, and not put it in a library routine.

@Kanagavelu Sugumar 2013-11-06 13:35:33

@Devin I am seeing that this also using native API like throwable. So How fast it is compared to other methods like StackTrace ..?

@Adam Jensen 2014-08-19 01:28:03

Will this create an anonymous inner class during compile time even if you put this code in a catch block?

@Brett Okken 2015-02-17 02:19:28

@AdamJensen, the class will be created/compiled at compile time, but instances will only be created if executed in the catch block.

@Lilo 2015-03-27 13:36:15

Thanks for the tips ! Instead of creating a new object, just use this.getClass().getEnclosingMethod().getName();

@cloudsurfin 2015-04-10 23:24:09

What about for static methods? "non-static variable this cannot be ref'd from a static context"

@wutzebaer 2016-08-13 22:30:01

is it possible to get the values of the parameters when calling .getEnclosingMethod().getParameters() ?

@Adowrath 2017-02-23 15:43:45

@wutzebaer No. The Method object only concerns the method and has no information about the current, or any, invocation of it.

@Hazel Troost 2017-09-20 16:25:41

@Lilo incorrect. getEnclosingMethod gets the name of the method where the class is defined. this.getClass() won't help you at all. @wutzebaer why would you even need to? You have access to them already.

@Jay 2014-02-19 07:13:45

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

@mike rodent 2016-10-23 10:28:18

Yes, by far the best... turn it into a method and get the third ([2]) frame (or whatever it's called) in the trace.

@ran 2013-06-03 11:46:39

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

@alexsmail 2013-07-07 13:25:41

See answers of mvanle virgo47 above and comment of thorbjorn-ravn-andersen. Repetion, non-accurate and non-reliable code.

@Maarten Bodewes 2014-04-15 10:12:25

@ShivaKomuravelly Yes, but not in any situation it seems, so -1 from me as well.

@alexsmail 2013-03-13 05:21:06

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

name will have value foo.

@eigil 2013-11-29 15:33:12

Local.class.getEnclosingMethod() was null. jdk1.6.0_31, play 1.2.5

@Maarten Bodewes 2014-04-15 10:07:28

@eigil that's interesting but without more info it is hard to tell what went "wrong" or when we should expect null

@Maarten Bodewes 2014-04-15 10:25:07

This is the same trick as this answer. It has the advantage that it does not create a spurious object instance, it has the disadvantage that it requires a class declaration which cannot be inlined in the statement (i.e. normally it requires an additional line of code).

@D.N. 2015-03-10 17:22:13

@eigil did you define the class within a class (example SomeClass), or within a method (example foo)? I found that defining a subclass without being wrapped in a method - or in a constructor - will cause getEnclosingMethod() to return null.

@eigil 2015-03-26 11:24:51

Pretty sure I did exactly as described in this answer. I think it's something strange with playframework. Tested in 'normal' java without any problem.

@Sumit Singh 2012-06-12 07:44:19

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);

@Zack Macomber 2013-02-05 20:17:50

This prints off "getStackTrace" for me - I'm using Java 1.5

@el-teedee 2018-02-28 14:29:20

be carefull of empty array according to Bombe's answer and javadoc indication. Some JVM may not fill the stacktrace array?

@mvanle 2012-09-29 14:55:45

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

@Octavia Togami 2013-07-27 01:11:16

This in combination with @mklemenz's answer is a very fast and clean way to access stack info.

@user1563700 2012-07-30 17:40:37

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.

@Ibrahim Arief 2012-08-24 09:27:50

Fastest as in performance wise? Any micro-benchmark to support the claim?

@ach 2013-01-25 17:14:20

+1. Using a simple timed loop on 1.6, 1,000,000 iterations using this method took 1219ms, while using new Throwable().getStackTrace() took 5614ms.

@avanderw 2014-01-23 09:47:01

m.setAccessible(true); should be surrounded by AccessController.doPrivileged. Something to consider, not a hard rule I would say

@Ryan 2016-06-30 17:54:18

Tested in 2016 and this continues to be the fastest. Like @ach I used 1M iterations. 1.7_79: 1.6s vs 15.2s 1.8_74: 1.8s vs 16.0s. FWIW my benchmark ste array's length==23 but this method stays fast regardless of stack depth.

@VonC 2009-01-14 12:33:28

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.

@Prof. Falken 2011-05-25 12:50:13

It only says "main" for me. :-/

@VonC 2011-05-25 14:28:55

@Amigable: did you try to print the all StackTraceElement array for debugging purpose and to see if 'main' is actually the right method?

@bluish 2011-12-28 13:15:34

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. See also @virgo47's answer.

@VonC 2011-12-28 16:01:35

@bluish: good point. I have included your comment and a reference to virgo47's answer in mine.

@mmm 2020-03-29 15:35:47

@VonC Is this implementation really correct? depth here must be ste.length + 1 for that to give current method. Should it not be ste[depth + 1] if we are to allow depth = 0 ?

@VonC 2020-03-29 16:46:11

@mmm It was, when I wrote that answer eleven years ago. I do mention virgo47's answer in my own post, and I have upvoted your answer.

@mmm 2020-03-29 18:39:44

@VonC Ok, thank you. Any reason why you do not edit your answer instead? Is it right in some cases?

@mmm 2020-03-29 18:40:55

@VonC Wait, are you saying that the JVM has modified the implementation and order of stacktraces in latter JDK versions? Initially I felt my memory also said stacktraces were pushed to. Now they are shifted. Wierd if that is true.

@VonC 2020-03-29 18:57:46

@mmm I am just saying I don't remember my exact environment when I wrote this. But I did acknowledge other answers as being more accurate.

@virgo47 2011-12-21 16:13:03

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

@Thorbjørn Ravn Andersen 2013-04-15 08:56:34

This is still subtly vendor dependent. The JVM is not required to deliver reliable data for this code.

@Thorbjørn Ravn Andersen 2013-04-16 14:22:32

Per the JVM spec the JVM is not required to provide full stack traces (optimization, inlining and all that) and you've already discovered that your heuristic changed between Oracle Java 5 and Oracle Java 6. There is nothing guaranteeing that any other JVM will behave as you expect in your code, so you are subtly relying on vendor specific behavior. Which is perfectly fine, as long as you are aware of that, but if - for instance - you need to deploy on an IBM JVM (which we must) or on a Zing instance you may have to revisit your heuristic.

@Ian 2018-03-04 01:41:05

This seems the most robust of all the options presented here, dependencies notwithstanding.

Related Questions

Sponsored Content

42 Answered Questions

[SOLVED] "implements Runnable" vs "extends Thread" in Java

43 Answered Questions

[SOLVED] How do I efficiently iterate over each entry in a Java Map?

31 Answered Questions

[SOLVED] What's the simplest way to print a Java array?

  • 2009-01-03 20:39:39
  • Alex Spurling
  • 2325742 View
  • 1971 Score
  • 31 Answer
  • Tags:   java arrays printing

28 Answered Questions

49 Answered Questions

[SOLVED] Does a finally block always get executed in Java?

21 Answered Questions

[SOLVED] How to get the current working directory in Java?

  • 2011-02-02 05:24:06
  • Qazi
  • 1373007 View
  • 1048 Score
  • 21 Answer
  • Tags:   java java-io

21 Answered Questions

[SOLVED] How can I get the current stack trace in Java?

  • 2009-07-01 13:13:01
  • ripper234
  • 528603 View
  • 1008 Score
  • 21 Answer
  • Tags:   stack-trace java

30 Answered Questions

[SOLVED] How to avoid Java code in JSP files?

  • 2010-07-05 07:24:06
  • chmoelders
  • 288127 View
  • 1686 Score
  • 30 Answer
  • Tags:   java jsp scriptlet

7 Answered Questions

Sponsored Content