I need to find the caller of a method. Is it possible using stacktrace or reflection?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
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).
As far as what the
realFramesToSkip
value should be, the Sun 1.5 and 1.6 VM versions ofjava.lang.System
, there is a package protected method called getCallerClass() which callssun.reflect.Reflection.getCallerClass(3)
, but in my helper utility class I used 4 since there is the added frame of the helper class invocation.An alternative solution can be found in a comment to this request for enhancement. It uses the
getClassContext()
method of a customSecurityManager
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
):An example of the output from my 2.4 GHz Intel Core 2 Duo MacBook running Java 1.6.0_17:
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 currentThread
. And among the non-internal ways of finding the caller class the customSecurityManager
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.
use this method:-
Caller of method example Code is here:-
OR
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)
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.