public final class ReflectiveCallerClassUtility extends Object
sun.reflect.Reflection.getCallerClass(int)
method.
Background: This method, available only in the Oracle/Sun/OpenJDK implementations of the Java
Virtual Machine, is a much more efficient mechanism for determining the Class
of the caller of a particular
method. When it is not available, a SecurityManager
is the second-best option. When this is also not
possible, the StackTraceElement[]
returned by Thread.getStackTrace()
must be used, and its
String
class name converted to a Class
using the slow Class.forName(java.lang.String)
.
As of Java 8, the getCallerClass(int)
method has been removed from Oracle/OpenJDK and is no longer usable. A
back-port of the feature that resulted in this change was made in Java 7u25, but the getCallerClass(int)
was
left around for that version and deprecated, with the intention of being removed in 7u40. By coincidence, the change
actually broke getCallerClass(int)
(the return value was inadvertently offset by 1 stack frame). This was
actually a good thing, because it made the hundreds of libraries and frameworks relying on this method aware of what
the JDK developers were up to.
After much community backlash, the JDK team agreed to restore getCallerClass(int)
and keep its existing
behavior for the rest of Java 7. However, the method is deprecated in Java 8, supposedly won't be in Java 9 (unless
no public API is exposed which may force them to keep it), and so backup options must be used. This class:
getCallerClass(int)
the traditional way when possible.getCallerClass(int)
with an adjusted offset in Oracle/OpenJDK 7u25.
IMPORTANT NOTE: This class should not be relied upon. It is considered an internal class and could
change at any time, breaking your code if you use it. Specifically, as a possible public API replacement for
getCallerClass(int)
develops in Java 9, this class is very likely to change or even go away.
Modifier and Type | Method and Description |
---|---|
static Class<?> |
getCaller(int depth)
Reflectively calls
getCallerClass(int) , compensating for the additional frame on the stack, and
compensating for the Java 7u25 bug if necessary. |
static boolean |
isSupported()
Indicates whether
getCallerClass(int) can be used on this JVM. |
public static boolean isSupported()
getCallerClass(int)
can be used on this JVM.true
if it can be used. If false
, getCaller(int)
should not be called. Use a backup
mechanism instead.public static Class<?> getCaller(int depth)
getCallerClass(int)
, compensating for the additional frame on the stack, and
compensating for the Java 7u25 bug if necessary. You should check with isSupported()
before using this
method.depth
- The depth of the caller to retrieve.null
if getCallerClass(int)
is not supported.Copyright © 1999-2015 Apache Software Foundation. All Rights Reserved.
Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, the Apache Logging project logo, and the Apache Log4j logo are trademarks of The Apache Software Foundation.