RetentionPolicy CLASS 与 RUNTIME

发布于 2024-11-06 09:32:56 字数 130 浏览 1 评论 0原文

RetentionPolicy.CLASSRetentionPolicy.RUNTIME 之间有什么实际区别?

看起来两者都被记录到字节码中并且无论如何都可以在运行时访问。

What is the practical difference between RetentionPolicy.CLASS and RetentionPolicy.RUNTIME?

It looks like both are recorded into the bytecode and both may be accessed at the run-time anyway.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

煮茶煮酒煮时光 2024-11-13 09:32:56

无论如何,两者都可以在运行时访问。

这不是 javadoc 所说的:

运行时:注释是由编译器记录在类文件中,并在运行时由VM保留,因此可以反射性地读取它们

CLASS:注释将由编译器记录在类文件中,但不需要在运行时由VM保留

在实践中,我不知道 CLASS 的任何用例。仅当您想以编程方式读取字节码(而不是通过类加载器 API)时,它才有用,但这是一个非常特殊的情况,我不知道为什么您不只使用 RUNTIME 。

讽刺的是,CLASS 是默认行为。

both may be accessed at the run-time anyway.

That's not what the javadoc says:

RUNTIME: Annotations are to be recorded in the class file by the compiler and retained by the VM at run time, so they may be read reflectively.

CLASS: Annotations are to be recorded in the class file by the compiler but need not be retained by the VM at run time.

In practice, I'm not aware of any use-cases for CLASS. It would only be useful if you wanted to read the bytecode programmatically, as opposed to via the classloader API, but that's a very specialised case, and I don't know why you wouldn't just use RUNTIME.

Ironically, CLASS is the default behaviour.

倚栏听风 2024-11-13 09:32:56

看起来两者都被记录到字节码中,并且无论如何都可以在运行时访问。

对于基本的内置注释接口(如 getAnnotations)为 False。例如:

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.CLASS)
@interface RetentionClass {}

@Retention(RetentionPolicy.RUNTIME)
@interface RetentionRuntime {}

public static void main(String[] args) {
    @RetentionClass
    class C {}
    assert C.class.getAnnotations().length == 0;

    @RetentionRuntime
    class D {}
    assert D.class.getAnnotations().length == 1;
}

观察 RetentionPolicy.CLASS 注释的唯一方法是使用字节码解析器。

另一个区别是 Retention.CLASS 带注释的类获得 RuntimeInvisible 类属性,而 Retention.RUNTIME 注释获得 RuntimeVisible 类属性。这可以通过javap观察到。

GitHub 上的示例供您玩和。

It looks like both are recorded into the bytecode and both may be accessed at the run-time anyway.

False for basic built-in annotation interfaces like getAnnotations. E.g.:

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.CLASS)
@interface RetentionClass {}

@Retention(RetentionPolicy.RUNTIME)
@interface RetentionRuntime {}

public static void main(String[] args) {
    @RetentionClass
    class C {}
    assert C.class.getAnnotations().length == 0;

    @RetentionRuntime
    class D {}
    assert D.class.getAnnotations().length == 1;
}

so the only way to observe a RetentionPolicy.CLASS annotation is by using a bytecode parser.

Another difference is that the Retention.CLASS annotated class gets a RuntimeInvisible class attribute, while Retention.RUNTIME annotations get a RuntimeVisible class attribute. This can be observed with javap.

Examples on GitHub for you to play with.

糖粟与秋泊 2024-11-13 09:32:56

默认情况下,无法通过反射 API 访问注释。
(RetentionPolicy.CLASS 是默认保留策略)

您可以指定自定义注释是否应在运行时可用,以便通过反射进行检查。您可以通过使用 @Retention 注释来注释您的注释定义来实现此目的。

尝试这个简单的示例

@Retention(RetentionPolicy.RUNTIME)
public @interface Version {
    int test();
}

@Version(test= 1)
public class Engineer{
   //code
}

public class Main {
        
    public static void main(String[] args) {
        Engineer engineer = new Engineer();
    
        Annotation[] annotations = engineer.getClass().getAnnotations();
        System.out.printf("%d annotations found.", annotations.length);
    }
}

尝试通过将 Version 注释的 RetentionPolicy 更改为 RetentionPolicy.CLASS 来再次运行代码,并检查差异。

By default, annotations are not accessible through Reflection APIs.
(RetentionPolicy.CLASS is the default retention policy)

You can specify for your custom annotation if it should be available at runtime, for inspection via reflection. You do so by annotating your annotation definition with the @Retention annotation.

Try this simple example

@Retention(RetentionPolicy.RUNTIME)
public @interface Version {
    int test();
}

@Version(test= 1)
public class Engineer{
   //code
}

public class Main {
        
    public static void main(String[] args) {
        Engineer engineer = new Engineer();
    
        Annotation[] annotations = engineer.getClass().getAnnotations();
        System.out.printf("%d annotations found.", annotations.length);
    }
}

Try to run the code again by changing the RetentionPolicy of the Version annotation to RetentionPolicy.CLASS and check the difference.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文