This article explains the differences between Java's RetentionType
enums used on annotations.
If you look at the source code of annotations, it's very common to see a @Retention
annotation. The value passed to the @Retention
annotation is a RetentionPolicy
enum. What are the differences of the enum values? Find out in this article.
RetentionPolicy.SOURCE
If this enum is used, the annotation will be discarded by the compiler. After the code has been compiled, the annotation is not useful anymore and therefore it's not written to the bytecode.
For example, there is an annotation whose retention policy is SOURCE
.
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface MySourceAnnotation {
String value() default "";
}
If a class named MyBean
uses the annotation and you open the generated .class
file, you will not find the annotation.
If you get the annotation list of the class using getAnnotations
(e.g. MyBean.class.getAnnotations()
), you will not find MySourceAnnotation
.
Some annotations that use this retention type are @Override
and @SuppressWarnings
.
RetentionPolicy.CLASS
This is the default type. If an annotation uses this type, it means the annotation is recorded in the file, but it will not be retained at the run time by the VM.
For example, there is an annotation whose retention policy is CLASS
.
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface MyClassAnnotation {
String value() default "";
}
If a class named MyBean
uses the annotation and you open the generated .class
file, you'll find the annotation name preceded by RuntimeInvisibleAnnotations
.
RuntimeInvisibleAnnotations...com/woolha/example/annotations/MyClassAnnotation
If you get the annotation list of the class using getAnnotations
(e.g. MyBean.class.getAnnotations()
), you will not find MyClassAnnotation
.
Despite being the default type, it's not common to use it. It can be useful if you want to get the annotation by reading the bytecode programmatically. The GwtCompatible
annotation of Google Guava library uses this retention type.
RetentionPolicy.RUNTIME
If this enum is used, the annotation is recorded in the class file and retained at the run time. In addition, you can get the annotation using reflection.
For example, there is an annotation whose retention policy is RUNTIME
.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyRuntimeAnnotation {
String value() default "";
}
If a class named MyBean
uses the annotation and you open the generated .class
file, you'll find the annotation name preceded by RuntimeVisibleAnnotations
.
RuntimeVisibleAnnotations...com/woolha/example/annotations/MyRuntimeAnnotation
If you get the annotation list of the class using getAnnotations
(e.g. MyBean.class.getAnnotations()
), you will find MyRuntimeAnnotation
.
The @Deprecated
annotation uses this retention type.
Summary
The retention type affects whether an annotation is recorded in the class file and retained at the run time. Having understood the difference between those types, you should choose the correct one if you create a custom annotation.