Java-RetentionPolicy类别与运行时

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

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

Dima asked 2020-07-27T21:09:33Z
2个解决方案
53 votes

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

那不是javadoc所说的:

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

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

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

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

skaffman answered 2020-07-27T21:10:10Z
4 votes

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

对于基本的内置注释接口(例如Retention.CLASS)为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;
}

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

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

GitHub上的示例供您使用。

translate from https://stackoverflow.com:/questions/5971234/retentionpolicy-class-vs-runtime