RetentionPolicy CLASS与RUNTIME

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RetentionPolicy CLASS与RUNTIME相关的知识,希望对你有一定的参考价值。

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

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

答案

无论如何都可以在运行时访问它们。

这不是javadoc所说的:

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

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

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

具有讽刺意味的是,CLASS是默认行为。

另一答案

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

对于像getAnnotations这样的基本内置注释接口,这是假的。例如。:

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观察到。

Examples on GitHub供你玩。

另一答案

可以从类字节代码访问具有保留策略CLASSRUNTIME的注释。我们需要使用字节代码操作库(例如ASM)来访问字节代码中可用的Annotations。

这里有一个简单的例子 - http://bethecoder.com/applications/tutorials/java/annotations/class-and-runtime-retention-policy.html

以上是关于RetentionPolicy CLASS与RUNTIME的主要内容,如果未能解决你的问题,请参考以下文章

自定义注解之运行时注解(RetentionPolicy.RUNTIME)

java注解使用

@Retention作用详析

java @Retention元注解

Java注解

Java元注解