12

having the method

public void foo(){
  //..    
}

Is there a way to get the methodName (in this case foo) at runtime?

I know how to get the classname via

this.getClass().getName()

or to get all public methods via Method[] methods = this.getClass().getMethods(); Once I have the method name the parameters would also be important as there could be several methods with same name

Martin Dürrmeier
  • 1,653
  • 5
  • 18
  • 35
  • possible duplicate of [Getting the name of the current executing method](http://stackoverflow.com/questions/442747/getting-the-name-of-the-current-executing-method) – bmargulies Dec 28 '11 at 12:23

6 Answers6

5

Reflection is one way. Another slow and potentially unreliable way is with a stack trace.

StackTraceElement[] trace = new Exception().getStackTrace();
String name = trace[0].getMethodName();

Same idea but from the thread:

StackTraceElement[] trace = Thread.currentThread().getStackTrace();
String name = trace[0].getMethodName();
Jonathon Faust
  • 12,396
  • 4
  • 50
  • 63
  • 1
    why is it unreliable? do you have an example for getting it via reflection? – Martin Dürrmeier Jun 29 '10 at 15:37
  • @Martin Dürrmeier - reflection is more involved. I've added links for information about the `getStackTrace` method and potential unreliability. – Jonathon Faust Jun 29 '10 at 15:47
  • thanks for the link. Could you give me a hint how to do it via Reflection? – Martin Dürrmeier Jun 30 '10 at 06:07
  • @Martin Dürrmeier - Usually with reflection you know the method name beforehand. Using a `Class` object, you can call `getMethods` and match up the name with the proper argument types to get a `Method` object. Check out the JavaDoc for `Class`: http://java.sun.com/javase/6/docs/api/java/lang/Class.html – Jonathon Faust Jun 30 '10 at 11:24
5

I'm not sure why you need to do this, but you can always create a new Throwable() and getStackTace(), then query StackTraceElement.getMethodName().

As a bonus, you get the whole stack trace up to the execution point, not just the immediately enclosing method.

Related questions

Community
  • 1
  • 1
polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
  • Thanks! I'm creating CommonBaseEvents need apart from the className the MethodName see also http://download.boulder.ibm.com/ibmdl/pub/software/dw/library/autonomic/books/cbepractice/index.htm#_Toc130892562 – Martin Dürrmeier Jun 29 '10 at 15:36
  • 1
    Jonathon pointed out what the JavaDoc of 'getStackTace()' says "Some virtual machines may, under some circumstances, omit one or more stack frames from the stack trace." So i'm trying reflection. Do you have an idea how it works via Reflection? – Martin Dürrmeier Jun 30 '10 at 06:45
5

I use code like the following:

  /**
   * Proper use of this class is
   *     String testName = (new Util.MethodNameHelper(){}).getName();
   *  or
   *     Method me = (new Util.MethodNameHelper(){}).getMethod();
   * the anonymous class allows easy access to the method name of the enclosing scope.
   */
  public static class MethodNameHelper {
    public String getName() {
      final Method myMethod = this.getClass().getEnclosingMethod();
      if (null == myMethod) {
        // This happens when we are non-anonymously instantiated
        return this.getClass().getSimpleName() + ".unknown()"; // return a less useful string
      }
      final String className = myMethod.getDeclaringClass().getSimpleName();
      return className + "." + myMethod.getName() + "()";
    }

    public Method getMethod() {
      return this.getClass().getEnclosingMethod();
    }
}

Just leave off the className + "." part and see if it meets your needs.

Jim
  • 1,161
  • 9
  • 21
2

Use this code:

System.out.println(new Throwable().getStackTrace()[0].getMethodName());
RaZieRSarE
  • 89
  • 4
1

You can hard code the name.

// The Annotation Processor will complain if the two method names get out of synch
class MyClass
{
    @HardCodedMethodName ( ) 
     void myMethod ( )
     {
          @ HardCodedMethodName // Untried but it seems you should be able to produce an annotation processor that compile time enforces that myname = the method name.
          String myname = "myMethod" ;
          ...
     }
}
emory
  • 10,725
  • 2
  • 30
  • 58
0

This question was asked years ago, but I think it would be worth synthesize the previous answers in a simpler expression:

String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();

In spite of its ugliness and the reliability issues cited, it is clean and can be easily used with Log.x() functions to help in debugging.

keyser
  • 18,829
  • 16
  • 59
  • 101
Miguel Dutra
  • 76
  • 1
  • 7