sun.reflect.CallerSensitive注释是什么意思?

时间:2014-03-25 06:19:14

标签: java class reflection classloader

@CallerSensitive注释隐含在方法之上的含义是什么?

例如,注释存在于Class

的getClassLoader方法中
 @CallerSensitive
    public ClassLoader getClassLoader() {
    //
    }

2 个答案:

答案 0 :(得分:43)

根据我在评论中链接的JEP(也是here),

  

调用者敏感方法根据类别改变其行为   它的直接来电者。它通过调用发现它的调用者类   sun.reflect.Reflection.getCallerClass方法。

如果你看一下Class#forName(String)

的实现
@CallerSensitive
public static Class<?> forName(String className)
            throws ClassNotFoundException {
    return forName0(className, true,
                    ClassLoader.getClassLoader(Reflection.getCallerClass()));
}

,您注意到它正在使用Reflection.getCallerClass()。如果我们看一下那个方法

  

返回调用此方法的方法的调用者的类,忽略与java.lang.reflect.Method.invoke()关联的框架及其实现。

@CallerSensitive
public static native Class getCallerClass();

在这个JEP之前,问题似乎是如果调用者敏感方法是通过反射而不是直接调用的,那么必须有一个复杂的过程来识别实际的调用类是什么。如果通过反射调用该方法,则会出现问题。使用@CallerSensitive提出(并引入)了一个更简单的过程。

基本上,JVM使用@CallerSensitive注释

  

JVM将跟踪此注释,并可选择强制执行   sun.reflect.Reflection.getCallerClass方法可以不变的   仅在标记该方法时报告方法的调用者   这个注释。

答案 1 :(得分:0)

来自jdk.internal.reflect.CallerSensitive

  

注释为@CallerSensitive的方法对其调用类敏感,   通过Reflection.getCallerClass或其他等效方法。

从Java SE 9开始,等效项为java.lang.StackWalker.getCallerClass

这实际上是Java版本1.0和1.1的安全模型,该模型实现了某种贫乏的链接程序检查。除了与反射相关的任何事物外,这是一种连贯的方法,但极其脆弱。另一方面,限制性更强的Java 2安全模型是魔术,没有显示其工作原理。

@CallerSensitive方法会根据调用它们的类来更改行为。这总是令人惊讶,但是Java 2堆栈检查安全模型也是如此。更糟糕的是,这些方法调用对于代表其调用方的类特别有用,因此上下文始终是错误的。

Secure Coding Guidelines for Java SE涵盖了这一领域。

Java SE 9中模块的引入意味着某些细节已更改。

另外,如果用@CallerSensitive调用了Method.invoke方法,则getCallerClass将忽略某些堆栈帧。在内部,JDK使用“蹦床” ClassLoader充当良性假呼叫者。 java.lang.invoke.MethodHandle复制了Method.invoke的问题。 AccessController.doPrivileged方法也存在问题,规范的后果令人惊讶。

JEP 176: Mechanical Checking of Caller-Sensitive Methods处理特定的@CallerSensitive jdk内部注释。 《指南》中的方法列表是由FindBugs插件生成的,但随后进行了手动更新。