Annotation RetentionPolicy 区别
RetentionPolicy做为一个enum类, 有三个值。
- RetentionPolicy.SOURCE: 其生命周期只存在于source code这个阶段, 在compile的时候, 这类annotation会被JVM所丢弃。当编译完成后, 这类annotation是没有用处的。如:
@Override
,@SuppressWarnings
@Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override { }
- RetentionPolicy.CLASS: RetentionPolicy默认为 CLASS, 当class被加载时, 此类annotation被丢弃。(感觉很少有使用CLASS的情况)
- RetentionPolicy.RUNTIME: 存在于整个JVM运行环境中。 如:@Deprecated
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE}) public @interface Deprecated { }
Code Example:
importjava.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * */ public class RetentionPolicyDemo { @Retention(RetentionPolicy.SOURCE) @interface RetentionSource {} @Retention(RetentionPolicy.CLASS) @interface RetentionClass {} @Retention(RetentionPolicy.RUNTIME) @interface RetentionRuntime {} public static void main(String[] args) { @RetentionSource class B {} System.out.println(B.class.getAnnotations().length ); // Result: 0 @RetentionClass class C {} System.out.println(C.class.getAnnotations().length ); // Result: 0 @RetentionRuntime class D {} System.out.println(D.class.getAnnotations().length ); // Result: 1 } }
只有RetentionPolicy.RUNTIME 返回大于0的length.
字节码demo:
@Retention(RetentionPolicy.CLASS) @Target(ElementType.TYPE) public @interface Anno { }
@Anno public class AnnoTest { @Deprecated public void test() { } }
Constant pool:
#1 = Methodref #3.#19 // java/lang/Object."<init>":()V
#2 = Class #20 // com/my/java/lang/annotation/retentio
#3 = Class #21 // java/lang/Object
#4 = Utf8 <init>
#5 = Utf8 ()V
#6 = Utf8 Code
#7 = Utf8 LineNumberTable
#8 = Utf8 LocalVariableTable
#9 = Utf8 this
#10 = Utf8 Lcom/my/java/lang/annotation/retentionPolicy/AnnoTest;
#11 = Utf8 test
#12 = Utf8 Deprecated
#13 = Utf8 RuntimeVisibleAnnotations
#14 = Utf8 Ljava/lang/Deprecated;
#15 = Utf8 SourceFile
#16 = Utf8 AnnoTest.java
#17 = Utf8 RuntimeInvisibleAnnotations
#18 = Utf8 Lcom/my/java/lang/annotation/retentionPolicy/Anno;
#19 = NameAndType #4:#5 // "<init>":()V
#20 = Utf8 com/my/java/lang/annotation/retentionPolicy/AnnoTest
从红色字体中可以看出RetentionPolicy.RUNTIME为RuntimeVisibleAnnotations。
RetentionPolicy.CLASS为RuntimeInvisibleAnnotations