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

2022-09-01 06:50:20

上述方法的注释暗示了什么?@CallerSensitive

例如,注释存在于类的getClassLoader方法中。

 @CallerSensitive
    public ClassLoader getClassLoader() {
    //
    }

答案 1

根据我在评论中链接的JEP(也在这里),

对调用方敏感的方法根据其直接调用方的类改变其行为。它通过调用该方法来发现其调用方的类。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


答案 2

jdk.internal.reflect.CallerSensitive

@CallerSensitive注释的方法通过其反射.getCallerClass或通过某些等效项对其调用类敏感。

等效项是从 Java SE 9 开始的。java.lang.StackWalker.getCallerClass

这实际上是Java版本1.0和1.1的安全模型,它们实现了一种pauper的链接器检查。这是一种连贯的方法,除了与反射有关的任何东西,但非常脆弱。另一方面,限制性更强的Java 2安全模型是神奇的,并没有显示其工作原理。

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

Java SE 的安全编码指南涵盖了这一领域。

Java SE 9中模块的引入意味着一些细节已经改变。

此外,如果使用某些堆栈帧调用该方法,则 将被 忽略。在内部,JDK使用“蹦床”作为良性的假呼叫者。 复制 了 的问题。这些方法也存在问题,规范的后果令人惊讶。@CallerSensitiveMethod.invokegetCallerClassClassLoaderjava.lang.invoke.MethodHandleMethod.invokeAccessController.doPrivileged

JEP 176:调用方敏感方法的机械检查处理特定的jdk内部注释。指南中的方法列表由 FindBugs 插件生成,但随后手动更新。@CallerSensitive