Is there a way to get the name of the currently executing method in Java?
23 Answers
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
.
-
10This 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/… Commented May 4, 2012 at 10:52
-
7class Local {}; String name = Local.class.getEnclosingMethod().getName(); Commented Mar 13, 2013 at 5:16
-
27@shrini1000 the idea is to use this snippet where the information is needed, and not put it in a library routine. Commented Apr 15, 2013 at 8:54
-
4Thanks for the tips ! Instead of creating a new object, just use this.getClass().getEnclosingMethod().getName();– LiloCommented Mar 27, 2015 at 13:36
-
4@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.– Hazel TCommented Sep 20, 2017 at 16:25
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.
-
7Is this same pitfall true for stack traces in exceptions? Commented Mar 3, 2009 at 19:15
-
8Yes, it is. The documentation for Throwable.[getStackTrace()](download.oracle.com/javase/1.5.0/docs/api/java/lang/… contains the exact same paragraph.– BombeCommented Nov 11, 2011 at 16:50
-
4The 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. Commented Apr 15, 2013 at 8:53
-
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.– GusCommented Jul 6, 2013 at 21:48
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 writeste[2 + depth].getMethodName().
0
isgetStackTrace()
,1
isgetMethodName(int depth)
and2
is invoking method.
virgo47's answer (upvoted) actually computes the right index to apply in order to get back the method name.
-
2
-
@Amigable: did you try to print the all
StackTraceElement
array for debugging purpose and to see if 'main' is actually the right method?– VonCCommented May 25, 2011 at 14:28 -
7I use JRE 6 and gives me incorrect method name. It works if I write
ste[2 + depth].getMethodName()
. 0 isgetStackTrace()
, 1 isgetMethodName(int depth)
and 2 is invoking method. See also @virgo47's answer.– bluishCommented Dec 28, 2011 at 13:15 -
2@bluish: good point. I have included your comment and a reference to virgo47's answer in mine.– VonCCommented Dec 28, 2011 at 16:01
-
@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 ?– mjsCommented Mar 29, 2020 at 15:35
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. :-)
-
2This is still subtly vendor dependent. The JVM is not required to deliver reliable data for this code. Commented Apr 15, 2013 at 8:56
-
7Per 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. Commented Apr 16, 2013 at 14:22
-
1This seems the most robust of all the options presented here, dependencies notwithstanding.– IanCommented Mar 4, 2018 at 1:41
java.lang.StackWalker
, Java 9+
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.
-
4
-
1
Both of these options work for me with Java:
new Object(){}.getClass().getEnclosingMethod().getName()
Or:
Thread.currentThread().getStackTrace()[1].getMethodName()
-
3for static methods use: <Class>.class.getEnclosingMethod().getName() Commented May 31, 2017 at 10:21
-
be carefull of empty array according to Bombe's answer and javadoc indication. Some JVM may not fill the stacktrace array? Commented Feb 28, 2018 at 14:29
public class SomeClass {
public void foo(){
class Local {};
String name = Local.class.getEnclosingMethod().getName();
}
}
name will have value foo.
-
6Local.class.getEnclosingMethod() was null. jdk1.6.0_31, play 1.2.5– eigilCommented Nov 29, 2013 at 15:33
-
@eigil that's interesting but without more info it is hard to tell what went "wrong" or when we should expect
null
Commented Apr 15, 2014 at 10: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). Commented Apr 15, 2014 at 10:25
-
@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.– D.N.Commented Mar 10, 2015 at 17:22
-
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.– eigilCommented Mar 26, 2015 at 11:24
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.
-
3Fastest as in performance wise? Any micro-benchmark to support the claim? Commented Aug 24, 2012 at 9:27
-
10+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.– achCommented Jan 25, 2013 at 17:14 -
1m.setAccessible(true); should be surrounded by AccessController.doPrivileged. Something to consider, not a hard rule I would say– avanderwCommented Jan 23, 2014 at 9:47
-
6Tested 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.– RyanCommented Jun 30, 2016 at 17:54
-
1@Dennie even if there was that method,
setAccessible(true)
would fail nowadays.– HolgerCommented May 17, 2023 at 9:18
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);
-
2This prints off "getStackTrace" for me - I'm using Java 1.5 Commented Feb 5, 2013 at 20:17
-
be carefull of empty array according to Bombe's answer and javadoc indication. Some JVM may not fill the stacktrace array? Commented Feb 28, 2018 at 14:29
public static String getCurrentMethodName() {
return Thread.currentThread().getStackTrace()[2].getClassName() + "." + Thread.currentThread().getStackTrace()[2].getMethodName();
}
-
Yes, by far the best... turn it into a method and get the third ([2]) frame (or whatever it's called) in the trace. Commented Oct 23, 2016 at 10:28
-
1Don’t repeat yourself. Especially when the repeated expression is an extremely expensive one, like
Thread.currentThread().getStackTrace()
. That’s what local variables are for, to store the result of an evaluation so you can use the result multiple times instead of repeating the evaluation.– HolgerCommented May 17, 2023 at 9:13
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 + ")";
}
}
-
3This in combination with @mklemenz's answer is a very fast and clean way to access stack info. Commented Jul 27, 2013 at 1:11
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
-
In recent testing on Android, it worked better for me to use
getStackTrace()[0]
rather thangetStackTrace()[1]
. YMMV.– mbm29414Commented Mar 21, 2016 at 15:23 -
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
}
}
-
final StackTraceElement e = Thread.currentThread().getStackTrace()[2];
works;e.getClassName();
return the full class name ande.getMethodName()
return the methon name.– MarksCommented Nov 26, 2015 at 12:05 -
2
getStackTrace()[2]
is wrong, it has to begetStackTrace()[3]
because: [0] dalvik.system.VMStack.getThreadStackTrace [1] java.lang.Thread.getStackTrace [2] Utils.getCurrentClassAndMethodNames [3] The function a() calling this one– PhilLabCommented Jul 13, 2017 at 16:59
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());
String methodName =Thread.currentThread().getStackTrace()[1].getMethodName();
System.out.println("methodName = " + methodName);
-
1See answers of mvanle virgo47 above and comment of thorbjorn-ravn-andersen. Repetion, non-accurate and non-reliable code. Commented Jul 7, 2013 at 13:25
-
@ShivaKomuravelly Yes, but not in any situation it seems, so -1 from me as well. Commented Apr 15, 2014 at 10:12
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.
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())}));
}
}
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
-
1@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. Commented May 27, 2019 at 23:22
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)]
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
-
3Could 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. :(– XobotunCommented May 6, 2020 at 14:35
-
4@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.– XobotunCommented May 10, 2020 at 16:18
Preferred Solution for Java 9 or above:
private static String getCurrentMethodName() {
return StackWalker.getInstance()
.walk(frames -> frames.skip(1).findFirst().map(StackWalker.StackFrame::getMethodName))
.orElse("Anything");
}
StackWalker
has a few advantages:
- no need to create a dummy anonymous inner class instance, i.e.,
new Object().getClass() {}
- no need to eagerly capture the whole stack trace, which can be costly
Read more in this article.
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);
}
MethodHandles.lookup().lookupClass().getEnclosingMethod().getName();
-
13Please 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". Commented Sep 27, 2016 at 14:31
-
1Although 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. Commented Sep 28, 2016 at 8:27
-
1Only for Java 7+, but concise way to get the method name. Still, remains the performance considerations of such a call.– BenjCommented Oct 11, 2016 at 12:29
-
7
getEnclosingMethod()
throws aNullPointerException
for me in Java 7.– Markus LCommented Apr 7, 2017 at 9:47 -
2The 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.– stoveCommented Apr 25, 2018 at 7:21
StackWalker
. The answer you accepted long time ago is now obsolete.java.lang.StackWalker
solution in this Answer.