I need to find the caller of a method. Is it possible using stacktrace or reflection?
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::getStackTraceandThread::getStackTracereturn an array ofStackTraceElementobjects, which contain the class name and method name of each stack-trace element.
SecurityManager::getClassContextis a protected method, which allows aSecurityManagersubclass to access the class context.JDK-internal
sun.reflect.Reflection::getCallerClassmethod 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 StackFrames and get the first preceding StackFrame:
walker.walk(frames -> frames
.map(StackWalker.StackFrame::getDeclaringClass)
.skip(1)
.findFirst());