@CallerSensitive
注释隐含在方法之上的含义是什么?
例如,注释存在于Class
的getClassLoader方法中 @CallerSensitive
public ClassLoader getClassLoader() {
//
}
答案 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插件生成的,但随后进行了手动更新。