I need to find the caller of a method. Is it possible using stacktrace or reflection?
-
5Just wondering, but why would you need to do this? – Juliet Jan 07 '09 at 17:51
-
2I have a Parent class (MVC model) with a notifier event and only setters of my subclasses call this method. i dont want to litter my code with a redundant argument. I'd rather let the method in parent class figure out the setter that called it. – Sathish Jan 07 '09 at 17:56
-
33@Sathish Sounds like you should re-think that design – krosenvold Jan 07 '09 at 17:59
-
1Also agree that re-design is necessary. See my answer below. – Craig P. Motlin Jan 07 '09 at 18:09
-
@Sathish I know this is quite old, but the more common method of doing this would be to pass the caller in the constructor, so the child classes know the caller. The reasoning is that the stacktrace doesn't return the actual instance. If you are truly talking about subclassing, then it would be better to declare your superclass as an abstract class, and implement the common code in the parent that depends on the subclass data to use an abstract function to get that data from the subclass. – Armand Mar 07 '14 at 17:32
-
7@Juliet As part of refactoring a large chuck of code, recently I've changed a method that is used by many things. There is a certain way to detect if code was using the new method properly, so I was printing the class and line number that called it in those cases. Outside of logging, I see no real purpose for something like this. Although I kind of want to write API's now that throw a `DontNameYourMethodFooException` if the calling method is named foo. – Cruncher May 16 '14 at 20:06
-
8I find being able to get the caller of my method an invaluable debugging tool: which is how a web search brought me here. If my method is being called from multiple places, is it being called from the right location at the right time? Outside of debugging or logging, usefulness is probably limited at best, as @Cruncher mentions. – Ogre Psalm33 Aug 19 '14 at 12:11
14 Answers
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace()
According to the Javadocs:
The last element of the array represents the bottom of the stack, which is the least recent method invocation in the sequence.
A StackTraceElement
has getClassName()
, getFileName()
, getLineNumber()
and getMethodName()
.
You will have to experiment to determine which index you want
(probably stackTraceElements[1]
or [2]
).

- 21,587
- 28
- 106
- 187

- 46,244
- 33
- 149
- 164
-
8I should note that getStackTrace() still creates an Exception, so this isn't really faster--just more convenient. – Michael Myers Jan 07 '09 at 18:08
-
49Note that this method will not give you the caller, but only the *type of the caller*. You will not have a reference to the object calling your method. – Joachim Sauer Jan 07 '09 at 18:30
-
@mmyers: That's good to know, but I think it expresses the intent better than creating the throw-away exception, anyway. – Lawrence Dol Jan 08 '09 at 08:44
-
3Just a side note, but on a 1.5 JVM Thread.currentThread().getStackTrace() seems to be a lot slower than creating a new Exception() (approximately 3 times slower). But as already noted, you shouldn't be using code like this in a performance-critical area anyway. ;) A 1.6 JVM only seems to be ~10% slower and, as Software Monkey said, it expresses the intent better than the "new Exception" way. – GaZ Jul 07 '09 at 14:42
-
But GaZ, that implies that Thread.currentThread is a very expensive method indeed (which is called twice here, the only other code executed is the test whether the current thread equals this thread). I found that hard to believe frankly. – Eelco Feb 02 '10 at 05:22
-
23@Eelco Thread.currentThread() is cheap. Thread.getStackTrace() is expensive because, unlike Throwable.fillInStackTrace(), there's no guarantee the method is called by the same thread it's examining, so the JVM has to create a "safepoint" -- locking the heap and stack. See this bug report: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6375302 – David Moles Dec 08 '11 at 23:30
-
8@JoachimSauer do you know of a way to get a reference to the object calling the method? – jophde Jan 19 '15 at 22:31
-
Flagged this as "not an answer", because as pointed out by @JoachimSauer, this does not actually give you the object that called. – kontur Feb 16 '16 at 10:25
-
3I don't know why people are saying that this is not an answer because this can get the __method name__ and the __class name__ using the methods enlisted [here](https://www.tutorialspoint.com/java/lang/java_lang_stacktraceelement.htm). – Shraddheya Shendre Dec 21 '16 at 07:07
-
@shraddheya-shendre Ok. What about method params? Class can contain multiply methods with same name. – Alexiuscrow Nov 13 '17 at 18:31
-
@Alexiuscrow it might not be so useful at run time and it still won't give you the params, but if you are doing this for logging and you just want to know which overloaded method was called then you can use the getLineNumber() method to indicate precisely which method is being called. – Dylan Smith Aug 14 '18 at 13:50
Note: if you are using Java 9 or later you should use StackWalker.getCallerClass()
as described in Ali Dehghani's answer.
The comparison of different methods below is mostly interesting for historical reason.
An alternative solution can be found in a comment to this request for enhancement.
It uses the getClassContext()
method of a custom SecurityManager
and seems to be faster than the stack trace method.
The following program tests the speed of the different suggested methods (the most interesting bit is in the inner class SecurityManagerMethod
):
/**
* Test the speed of various methods for getting the caller class name
*/
public class TestGetCallerClassName {
/**
* Abstract class for testing different methods of getting the caller class name
*/
private static abstract class GetCallerClassNameMethod {
public abstract String getCallerClassName(int callStackDepth);
public abstract String getMethodName();
}
/**
* Uses the internal Reflection class
*/
private static class ReflectionMethod extends GetCallerClassNameMethod {
public String getCallerClassName(int callStackDepth) {
return sun.reflect.Reflection.getCallerClass(callStackDepth).getName();
}
public String getMethodName() {
return "Reflection";
}
}
/**
* Get a stack trace from the current thread
*/
private static class ThreadStackTraceMethod extends GetCallerClassNameMethod {
public String getCallerClassName(int callStackDepth) {
return Thread.currentThread().getStackTrace()[callStackDepth].getClassName();
}
public String getMethodName() {
return "Current Thread StackTrace";
}
}
/**
* Get a stack trace from a new Throwable
*/
private static class ThrowableStackTraceMethod extends GetCallerClassNameMethod {
public String getCallerClassName(int callStackDepth) {
return new Throwable().getStackTrace()[callStackDepth].getClassName();
}
public String getMethodName() {
return "Throwable StackTrace";
}
}
/**
* Use the SecurityManager.getClassContext()
*/
private static class SecurityManagerMethod extends GetCallerClassNameMethod {
public String getCallerClassName(int callStackDepth) {
return mySecurityManager.getCallerClassName(callStackDepth);
}
public String getMethodName() {
return "SecurityManager";
}
/**
* A custom security manager that exposes the getClassContext() information
*/
static class MySecurityManager extends SecurityManager {
public String getCallerClassName(int callStackDepth) {
return getClassContext()[callStackDepth].getName();
}
}
private final static MySecurityManager mySecurityManager =
new MySecurityManager();
}
/**
* Test all four methods
*/
public static void main(String[] args) {
testMethod(new ReflectionMethod());
testMethod(new ThreadStackTraceMethod());
testMethod(new ThrowableStackTraceMethod());
testMethod(new SecurityManagerMethod());
}
private static void testMethod(GetCallerClassNameMethod method) {
long startTime = System.nanoTime();
String className = null;
for (int i = 0; i < 1000000; i++) {
className = method.getCallerClassName(2);
}
printElapsedTime(method.getMethodName(), startTime);
}
private static void printElapsedTime(String title, long startTime) {
System.out.println(title + ": " + ((double)(System.nanoTime() - startTime))/1000000 + " ms.");
}
}
An example of the output from my 2.4 GHz Intel Core 2 Duo MacBook running Java 1.6.0_17:
Reflection: 10.195 ms.
Current Thread StackTrace: 5886.964 ms.
Throwable StackTrace: 4700.073 ms.
SecurityManager: 1046.804 ms.
The internal Reflection method is much faster than the others. Getting a stack trace from a newly created Throwable
is faster than getting it from the current Thread
. And among the non-internal ways of finding the caller class the custom SecurityManager
seems to be the fastest.
Update
As lyomi points out in this comment the sun.reflect.Reflection.getCallerClass()
method has been disabled by default in Java 7 update 40 and removed completely in Java 8. Read more about this in this issue in the Java bug database.
Update 2
As zammbi has found, Oracle was forced to back out of the change that removed the sun.reflect.Reflection.getCallerClass()
. It is still available in Java 8 (but it is deprecated).
Update 3
3 years after: Update on timing with current JVM.
> java -version
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)
> java TestGetCallerClassName
Reflection: 0.194s.
Current Thread StackTrace: 3.887s.
Throwable StackTrace: 3.173s.
SecurityManager: 0.565s.

- 4,870
- 1
- 27
- 21
-
Thanks for the comparison in speed. Is a StackTrace really that slow? – Kevin Parker Jun 21 '12 at 20:44
-
5Yes, it seems like that. But note that the timings I give in the example is for a million calls - so depending on how you are using this it might not be a problem. – Johan Kaving Jun 27 '12 at 11:09
-
1For me removing reflection from my project resulted in a 10x speed increase. – Kevin Parker Jun 27 '12 at 14:20
-
2Yes, reflection in general is slow (see e.g. http://stackoverflow.com/questions/435553/java-reflection-performance), but in this specific case using the internal sun.reflect.Reflection class is the fastest. – Johan Kaving Jun 28 '12 at 12:39
-
It doesn't make a difference to your benchmark, but for correctness I believe the security manager implementation needs to do a (callStackDepth+1) in there somewhere, since using the SecurityManager subclass adds an extra level of stack depth. – Jeremy Huiskamp Jul 31 '12 at 19:19
-
1It actually doesn't need to. You can verify it by modifying the code above to print the returned className (and I suggest reducing the loop count to 1). You will see that all methods return the same className - TestGetCallerClassName. – Johan Kaving Aug 07 '12 at 06:07
-
getClasscontext is totally awesome. And works on android too ! (on android that's 10x faster than getStackTrace) – njzk2 Nov 14 '12 at 17:23
-
Note that the reflection approach use vendor specific classes. It will only work on Oracle-based JVM's. That may or may not be important. – Thorbjørn Ravn Andersen Jun 25 '13 at 04:13
-
1
-
"getCallerClass is deprecated" Does that affect both the Reflection way and the SecurityManager way? – Daniel Ryan Jun 25 '14 at 21:32
-
Looks like it might be staying for now: http://bugs.java.com/view_bug.do?bug_id=8021946 – Daniel Ryan Jun 26 '14 at 01:51
-
Yes, and it's still available (but deprecated) in Java 8. It does not affect the SecurityManager way. – Johan Kaving Jun 27 '14 at 11:06
-
@JohanKaving, hi, may i know how I can get the calling method name using SecurityManager? In your answer, you are returning a hardcoded method name. `getClassContext()[callStackDepth].getName();` gets me the class name. I want to get the actual calling method name using security manager. Is this possible? Thanks! – iamkenos May 31 '17 at 09:08
-
@iamkenos I think you will need to use a stack trace in order to get the calling method name. You can do `new Throwable().getStackTrace()[callStackDepth].getMethodName()` – Johan Kaving Jun 19 '17 at 07:41
-
1@njzk2 `SecurityManager.getClassContext()` may return `null` on Android. Tested on SDK versions 16 and 22. – Andi Jul 07 '18 at 21:56
Java 9 - JEP 259: Stack-Walking API
JEP 259 provides an efficient standard API for stack walking that allows easy filtering of, and lazy access to, the information in stack traces. Before Stack-Walking API, common ways of accessing stack frames were:
Throwable::getStackTrace
andThread::getStackTrace
return an array ofStackTraceElement
objects, which contain the class name and method name of each stack-trace element.
SecurityManager::getClassContext
is a protected method, which allows aSecurityManager
subclass to access the class context.JDK-internal
sun.reflect.Reflection::getCallerClass
method which you shouldn't use anyway
Using these APIs are usually inefficient:
These APIs require the VM to eagerly capture a snapshot of the entire stack, and they return information representing the entire stack. There is no way to avoid the cost of examining all the frames if the caller is only interested in the top few frames on the stack.
In order to find the immediate caller's class, first obtain a StackWalker
:
StackWalker walker = StackWalker
.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
Then either call the getCallerClass()
:
Class<?> callerClass = walker.getCallerClass();
or walk
the StackFrame
s and get the first preceding StackFrame
:
walker.walk(frames -> frames
.map(StackWalker.StackFrame::getDeclaringClass)
.skip(1)
.findFirst());

- 46,221
- 15
- 164
- 151
Sounds like you're trying to avoid passing a reference to this
into the method. Passing this
is way better than finding the caller through the current stack trace. Refactoring to a more OO design is even better. You shouldn't need to know the caller. Pass a callback object if necessary.

- 26,452
- 17
- 99
- 126
-
6++ Knowing the caller is too much information. If you must, you could pass in an interface, but there is a good chance that a major refactoring is needed. @satish should post his code and let us have some fun with it :) – Bill K Jan 07 '09 at 18:19
-
19Valid reasons for wanting to do this exist. I've had a few occasions where I found it helpful during testing for instance. – Eelco Feb 02 '10 at 05:23
-
2@chillenious I know :) I've done it myself to create a method like `LoggerFactory.getLogger(MyClass.class)` where I didn't have to pass in the class literal. It's still rarely the right thing to do. – Craig P. Motlin Feb 02 '10 at 15:05
-
8
-
1A concrete example of when it might be the RIGHT design decision to get information about the caller is when implementing the .NET `INotifyPropertyChanged` interface. While this specific example isn't in Java, the same problem can manifest itself when trying to model fields/getters as strings for Reflection. – Chris Kerekes Jan 15 '16 at 17:13
Oneliner:
Thread.currentThread().getStackTrace()[2].getMethodName()
Note that you might need to replace the 2 with 1.

- 6,164
- 4
- 24
- 38
-
5Little correction for Android. `Thread.currentThread().getStackTrace()[3].getMethodName()` return caller method name – Qamar Dec 07 '20 at 11:05
This method does the same thing but a little more simply and possibly a little more performant and in the event you are using reflection, it skips those frames automatically. The only issue is it may not be present in non-Sun JVMs, although it is included in the runtime classes of JRockit 1.4-->1.6. (Point is, it is not a public class).
sun.reflect.Reflection
/** Returns the class of the method <code>realFramesToSkip</code>
frames up the stack (zero-based), ignoring frames associated
with java.lang.reflect.Method.invoke() and its implementation.
The first frame is that associated with this method, so
<code>getCallerClass(0)</code> returns the Class object for
sun.reflect.Reflection. Frames associated with
java.lang.reflect.Method.invoke() and its implementation are
completely ignored and do not count toward the number of "real"
frames skipped. */
public static native Class getCallerClass(int realFramesToSkip);
As far as what the realFramesToSkip
value should be, the Sun 1.5 and 1.6 VM versions of java.lang.System
, there is a package protected method called getCallerClass() which calls sun.reflect.Reflection.getCallerClass(3)
, but in my helper utility class I used 4 since there is the added frame of the helper class invocation.

- 15,916
- 4
- 42
- 66
-
17
-
7Noted. I did specify that it is not a public class, and the protected method getCallerClass() in java.lang.System is present across all the 1.5+ VMs I have looked at, including IBM, JRockit and Sun, but your assertion is conservatively sound. – Nicholas Jan 08 '09 at 19:05
-
6@Software Monkey, well as usual, "it all depends". Doing something like this to assist in debugging or test logging--especially if it never ends up in production code--or if the deployment target is strictly the developer's PC, will probably be fine. Anyone who still thinks otherwise even in such cases: you'd need to actually explain the "_really_ bad idea" reasoning better than just saying it's bad... – Mar 17 '13 at 21:29
-
8Also, by similar logic you could also argue that anytime you use a Hibernate-specific feature that isn't JPA compatible, that's always a "_really_ bad idea". Or if you're going to use Oracle-specific features which aren't available in other databases, it's a "_really_ bad idea". Sure it's a safer mindset and definitely good advice for certain uses, but automatically throwing away useful tools just because it won't work with a software configuration that you're, uh.. *not using at all*? That's a bit too inflexible and a little silly. – Mar 17 '13 at 21:39
-
@Perce for here and now solutions it works well. Problem comes if - for any reason - such solutions creep into production code, and eventually requirements change (like run on Azul or Google Application Engine) and then the maintenance crew have a serious problem if the code fail to run. Vendor specific classes are time bombs. – Thorbjørn Ravn Andersen Jun 25 '13 at 04:20
-
5The unguarded use of vendor specific classes will present a higher likelihood of problems, but one should determine a path to gracefully degrade if the class in question is not present (or is prohibited for some reason). A policy of flat-out refusal to use any vendor specific classes is, in my opinion, a little naive. Poke around in the source code of some of the libraries you use in production and see if any of them do this. (sun.misc.Unsafe perhaps ?) – Nicholas Jun 25 '13 at 14:03
/**
* 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 = new Throwable().getStackTrace();
//System. out.println(ste[ste.length-depth].getClassName()+"#"+ste[ste.length-depth].getMethodName());
return ste[ste.length - depth].getMethodName();
}
For example, if you try to get the calling method line for debug purpose, you need to get past the Utility class in which you code those static methods:
(old java1.4 code, just to illustrate a potential StackTraceElement usage)
/**
* Returns the first "[class#method(line)]: " of the first class not equal to "StackTraceUtils". <br />
* From the Stack Trace.
* @return "[class#method(line)]: " (never empty, first class past StackTraceUtils)
*/
public static String getClassMethodLine()
{
return getClassMethodLine(null);
}
/**
* Returns the first "[class#method(line)]: " of the first class not equal to "StackTraceUtils" and aclass. <br />
* Allows to get past a certain class.
* @param aclass class to get pass in the stack trace. If null, only try to get past StackTraceUtils.
* @return "[class#method(line)]: " (never empty, because if aclass is not found, returns first class past StackTraceUtils)
*/
public static String getClassMethodLine(final Class aclass)
{
final StackTraceElement st = getCallingStackTraceElement(aclass);
final String amsg = "[" + st.getClassName() + "#" + st.getMethodName() + "(" + st.getLineNumber()
+")] <" + Thread.currentThread().getName() + ">: ";
return amsg;
}
/**
* Returns the first stack trace element of the first class not equal to "StackTraceUtils" or "LogUtils" and aClass. <br />
* Stored in array of the callstack. <br />
* Allows to get past a certain class.
* @param aclass class to get pass in the stack trace. If null, only try to get past StackTraceUtils.
* @return stackTraceElement (never null, because if aClass is not found, returns first class past StackTraceUtils)
* @throws AssertionFailedException if resulting statckTrace is null (RuntimeException)
*/
public static StackTraceElement getCallingStackTraceElement(final Class aclass)
{
final Throwable t = new Throwable();
final StackTraceElement[] ste = t.getStackTrace();
int index = 1;
final int limit = ste.length;
StackTraceElement st = ste[index];
String className = st.getClassName();
boolean aclassfound = false;
if(aclass == null)
{
aclassfound = true;
}
StackTraceElement resst = null;
while(index < limit)
{
if(shouldExamine(className, aclass) == true)
{
if(resst == null)
{
resst = st;
}
if(aclassfound == true)
{
final StackTraceElement ast = onClassfound(aclass, className, st);
if(ast != null)
{
resst = ast;
break;
}
}
else
{
if(aclass != null && aclass.getName().equals(className) == true)
{
aclassfound = true;
}
}
}
index = index + 1;
st = ste[index];
className = st.getClassName();
}
if(resst == null)
{
//Assert.isNotNull(resst, "stack trace should null"); //NO OTHERWISE circular dependencies
throw new AssertionFailedException(StackTraceUtils.getClassMethodLine() + " null argument:" + "stack trace should null"); //$NON-NLS-1$
}
return resst;
}
static private boolean shouldExamine(String className, Class aclass)
{
final boolean res = StackTraceUtils.class.getName().equals(className) == false && (className.endsWith("LogUtils"
) == false || (aclass !=null && aclass.getName().endsWith("LogUtils")));
return res;
}
static private StackTraceElement onClassfound(Class aclass, String className, StackTraceElement st)
{
StackTraceElement resst = null;
if(aclass != null && aclass.getName().equals(className) == false)
{
resst = st;
}
if(aclass == null)
{
resst = st;
}
return resst;
}

- 1,262,500
- 529
- 4,410
- 5,250
-
I needed something that works with Java 1.4 and this answer was very helpful! Thank you! – RGO Mar 07 '14 at 06:03
I've done this before. You can just create a new exception and grab the stack trace on it without throwing it, then examine the stack trace. As the other answer says though, it's extremely costly--don't do it in a tight loop.
I've done it before for a logging utility on an app where performance didn't matter much (Performance rarely matters much at all, actually--as long as you display the result to an action such as a button click quickly).
It was before you could get the stack trace, exceptions just had .printStackTrace() so I had to redirect System.out to a stream of my own creation, then (new Exception()).printStackTrace(); Redirect System.out back and parse the stream. Fun stuff.

- 62,186
- 18
- 105
- 157
-
-
Nope, At least that's how I remember it, I haven't done it in a few years, but I'm pretty sure that newing an exception is just creating an object, and throwing the exception doesn't do anything to it except pass it to the catch() clause. – Bill K Jan 07 '09 at 18:05
-
-
No, since Java 5 there is a method on Thread to get the current stack as an array of StackTraceElements; it's still not cheap, but cheaper than the old exception-parsing solution. – Lawrence Dol Jan 08 '09 at 08:40
-
@Software Monkey Although I'm sure it's more appropriate, what makes you say that it's cheaper? I'd assume the same mechanism would be used, and if not, why make one slower when it does the same thing? – Bill K Jan 08 '09 at 17:11
-
@Bill: Because you don't have to first produce and then parse text output to get the information - it's already there in the array of objects that generated the text output to begin with. – Lawrence Dol Apr 18 '12 at 19:28
private void parseExceptionContents(
final Exception exception,
final OutputStream out)
{
final StackTraceElement[] stackTrace = exception.getStackTrace();
int index = 0;
for (StackTraceElement element : stackTrace)
{
final String exceptionMsg =
"Exception thrown from " + element.getMethodName()
+ " in class " + element.getClassName() + " [on line number "
+ element.getLineNumber() + " of file " + element.getFileName() + "]";
try
{
out.write((headerLine + newLine).getBytes());
out.write((headerTitlePortion + index++ + newLine).getBytes() );
out.write((headerLine + newLine).getBytes());
out.write((exceptionMsg + newLine + newLine).getBytes());
out.write(
("Exception.toString: " + element.toString() + newLine).getBytes());
}
catch (IOException ioEx)
{
System.err.println(
"IOException encountered while trying to write "
+ "StackTraceElement data to provided OutputStream.\n"
+ ioEx.getMessage() );
}
}
}

- 21,688
- 25
- 143
- 191
Here is a part of the code that I made based in the hints showed in this topic. Hope it helps.
(Feel free to make any suggestions to improve this code, please tell me)
The counter:
public class InstanceCount{
private static Map<Integer, CounterInstanceLog> instanceMap = new HashMap<Integer, CounterInstanceLog>();
private CounterInstanceLog counterInstanceLog;
public void count() {
counterInstanceLog= new counterInstanceLog();
if(counterInstanceLog.getIdHashCode() != 0){
try {
if (instanceMap .containsKey(counterInstanceLog.getIdHashCode())) {
counterInstanceLog= instanceMap .get(counterInstanceLog.getIdHashCode());
}
counterInstanceLog.incrementCounter();
instanceMap .put(counterInstanceLog.getIdHashCode(), counterInstanceLog);
}
(...)
}
And the object:
public class CounterInstanceLog{
private int idHashCode;
private StackTraceElement[] arrayStackTraceElements;
private int instanceCount;
private String callerClassName;
private StackTraceElement getProjectClasses(int depth) {
if(depth< 10){
getCallerClassName(sun.reflect.Reflection.getCallerClass(depth).getName());
if(getCallerClassName().startsWith("com.yourproject.model")){
setStackTraceElements(Thread.currentThread().getStackTrace());
setIdHashCode();
return arrayStackTraceElements[depth];
}
//+2 because one new item are added to the stackflow
return getProjectClasses(profundidade+2);
}else{
return null;
}
}
private void setIdHashCode() {
if(getNomeClasse() != null){
this.idHashCode = (getCallerClassName()).hashCode();
}
}
public void incrementaContador() {
this.instanceCount++;
}
//getters and setters
(...)
}

- 1,122
- 3
- 13
- 27
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
class DBConnection {
String createdBy = null;
DBConnection(Throwable whoCreatedMe) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(os);
whoCreatedMe.printStackTrace(pw);
try {
createdBy = os.toString();
pw.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class ThrowableTest {
public static void main(String[] args) {
Throwable createdBy = new Throwable(
"Connection created from DBConnectionManager");
DBConnection conn = new DBConnection(createdBy);
System.out.println(conn.createdBy);
}
}
OR
public static interface ICallback<T> { T doOperation(); }
public class TestCallerOfMethod {
public static <T> T callTwo(final ICallback<T> c){
// Pass the object created at callee to the caller
// From the passed object we can get; what is the callee name like below.
System.out.println(c.getClass().getEnclosingMethod().getName());
return c.doOperation();
}
public static boolean callOne(){
ICallback callBackInstance = new ICallback(Boolean){
@Override
public Boolean doOperation()
{
return true;
}
};
return callTwo(callBackInstance);
}
public static void main(String[] args) {
callOne();
}
}

- 18,766
- 20
- 94
- 101
use this method:-
StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
stackTraceElement e = stacktrace[2];//maybe this number needs to be corrected
System.out.println(e.getMethodName());
Caller of method example Code is here:-
public class TestString {
public static void main(String[] args) {
TestString testString = new TestString();
testString.doit1();
testString.doit2();
testString.doit3();
testString.doit4();
}
public void doit() {
StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
StackTraceElement e = stacktrace[2];//maybe this number needs to be corrected
System.out.println(e.getMethodName());
}
public void doit1() {
doit();
}
public void doit2() {
doit();
}
public void doit3() {
doit();
}
public void doit4() {
doit();
}
}

- 2,879
- 6
- 43
- 55
Short answer ReflectionUtils.getCallingClass(0)
Long answer (code, Groovy)
package my
import org.codehaus.groovy.reflection.ReflectionUtils
import java.lang.reflect.Field
import java.lang.reflect.Method
trait Reflector {
static String[] fieldNames() {
List<String> names = []
Arrays.asList(naturalFields()).forEach { Field fl -> names.add(fl.name) }
return names.toArray() as String[]
}
static Field[] naturalFields() {
return finalClass().getDeclaredFields().findAll { Field fl -> !fl.synthetic }.collect()
}
static Method[] naturalMethods() {
return finalClass().getDeclaredMethods().findAll { Method md -> !md.synthetic }.collect()
}
static Class finalClass() {
return ReflectionUtils.getCallingClass(0)
}
}
class Demo implements Reflector {
int archived = 0
int demo = 100
static void playToo() {
println finalClass()
}
}
println Demo.finalClass() // class my.Demo
println Demo.naturalFields() // [private int my.Demo.archived, private int my.Demo.demo]
println Demo.fieldNames() // [archived, demo]

- 858
- 2
- 9
- 19
Yes you can use the current threads stack trace.
Here's some sample code snippet that should get you not only the method name of the calling thread but also the class name and line number:
Thread thread = Thread.currentThread();
StackTraceElement[] stackTrace = thread.getStackTrace();
for (int i = 0; i < stackTrace.length; i++) {
System.out.println(stackTrace[i].getClassName() + " " + stackTrace[i].getMethodName() + " " + stackTrace[i].getLineNumber());
}

- 2,514
- 2
- 23
- 38