public final class ReflectionUtil
extends java.lang.Object
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 Throwable.getStackTrace()
must be used, and its String
class name converted to a
Class
using the slow Class.forName(java.lang.String)
(which can add an extra microsecond or more for each invocation
depending on the runtime ClassLoader hierarchy).
During Java 8 development, the sun.reflect.Reflection.getCallerClass(int)
was removed from OpenJDK, and this
change was back-ported to Java 7 in version 1.7.0_25 which changed the behavior of the call and caused it to be off
by one stack frame. This turned out to be beneficial for the survival of this API as the change broke hundreds of
libraries and frameworks relying on the API which brought much more attention to the intended API removal.
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, and current Java 9 development has not
addressed this API. Therefore, the functionality of this class cannot be relied upon for all future versions of Java.
It does, however, work just fine in Sun JDK 1.6, OpenJDK 1.6, Oracle/OpenJDK 1.7, and Oracle/OpenJDK 1.8. Other Java
environments may fall back to using Throwable.getStackTrace()
which is significantly slower due to
examination of every virtual frame of execution.
Modifier and Type | Class and Description |
---|---|
(package private) static class |
ReflectionUtil.PrivateSecurityManager |
Modifier and Type | Field and Description |
---|---|
private static java.lang.reflect.Method |
GET_CALLER_CLASS |
(package private) static int |
JDK_7u25_OFFSET |
private static Logger |
LOGGER |
private static ReflectionUtil.PrivateSecurityManager |
SECURITY_MANAGER |
private static boolean |
SUN_REFLECTION_SUPPORTED |
Modifier | Constructor and Description |
---|---|
private |
ReflectionUtil() |
Modifier and Type | Method and Description |
---|---|
static java.lang.Class<?> |
getCallerClass(java.lang.Class<?> anchor) |
static java.lang.Class<?> |
getCallerClass(int depth) |
static java.lang.Class<?> |
getCallerClass(java.lang.String fqcn) |
static java.lang.Class<?> |
getCallerClass(java.lang.String fqcn,
java.lang.String pkg) |
private static java.lang.String |
getCallerClassName(java.lang.String fqcn,
java.lang.String pkg,
java.lang.StackTraceElement... elements) |
static java.util.Stack<java.lang.Class<?>> |
getCurrentStackTrace() |
(package private) static java.lang.StackTraceElement |
getEquivalentStackTraceElement(int depth) |
private static boolean |
isValid(java.lang.StackTraceElement element) |
static boolean |
supportsFastReflection() |
static final int JDK_7u25_OFFSET
private static final Logger LOGGER
private static final boolean SUN_REFLECTION_SUPPORTED
private static final java.lang.reflect.Method GET_CALLER_CLASS
private static final ReflectionUtil.PrivateSecurityManager SECURITY_MANAGER
public static boolean supportsFastReflection()
public static java.lang.Class<?> getCallerClass(int depth)
static java.lang.StackTraceElement getEquivalentStackTraceElement(int depth)
private static boolean isValid(java.lang.StackTraceElement element)
public static java.lang.Class<?> getCallerClass(java.lang.String fqcn)
public static java.lang.Class<?> getCallerClass(java.lang.String fqcn, java.lang.String pkg)
public static java.lang.Class<?> getCallerClass(java.lang.Class<?> anchor)
private static java.lang.String getCallerClassName(java.lang.String fqcn, java.lang.String pkg, java.lang.StackTraceElement... elements)
public static java.util.Stack<java.lang.Class<?>> getCurrentStackTrace()