欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Annotation RetentionPolicy 区别

程序员文章站 2022-04-05 21:09:22
...

RetentionPolicy做为一个enum类, 有三个值。

  1. RetentionPolicy.SOURCE:  其生命周期只存在于source code这个阶段, 在compile的时候, 这类annotation会被JVM所丢弃。当编译完成后, 这类annotation是没有用处的。如: @Override@SuppressWarnings
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.SOURCE)
    public @interface Override {
    }
  2. RetentionPolicy.CLASS: RetentionPolicy默认为 CLASS, 当class被加载时, 此类annotation被丢弃。(感觉很少有使用CLASS的情况)
  3. 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