Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RetentionPolicy CLASS vs. RUNTIME

What is the practical difference between RetentionPolicy.CLASS and RetentionPolicy.RUNTIME?

It looks like both are recorded into the bytecode and both may be accessed at the run-time anyway.

like image 242
Dima Avatar asked May 11 '11 22:05

Dima


People also ask

What is RetentionPolicy runtime?

class file but are discarded during runtime. CLASS is the default retention policy in Java. RetentionPolicy. RUNTIME: The annotations annotated using the RUNTIME retention policy are retained during runtime and can be accessed in our program during runtime.

What is retention policy in Android?

Enum valuesAnnotations are to be recorded in the class file by the compiler but need not be retained by the VM at run time. RetentionPolicy. RUNTIME. Annotations are to be recorded in the class file by the compiler and retained by the VM at run time, so they may be read reflectively. RetentionPolicy.

What is retention policy in spring boot?

@Retention : Specifies whether the annotation metadata can be accessed at runtime by the application (will determine whether the compiled bytecode is affected).

What is @interface annotation in Java?

Annotation is defined like a ordinary Java interface, but with an '@' preceding the interface keyword (i.e., @interface ). You can declare methods inside an annotation definition (just like declaring abstract method inside an interface). These methods are called elements instead.


2 Answers

both may be accessed at the run-time anyway.

That's not what the javadoc says:

RUNTIME: Annotations are to be recorded in the class file by the compiler and retained by the VM at run time, so they may be read reflectively.

CLASS: Annotations are to be recorded in the class file by the compiler but need not be retained by the VM at run time.

In practice, I'm not aware of any use-cases for CLASS. It would only be useful if you wanted to read the bytecode programmatically, as opposed to via the classloader API, but that's a very specialised case, and I don't know why you wouldn't just use RUNTIME.

Ironically, CLASS is the default behaviour.

like image 54
skaffman Avatar answered Oct 03 '22 04:10

skaffman


It looks like both are recorded into the bytecode and both may be accessed at the run-time anyway.

False for basic built-in annotation interfaces like getAnnotations. E.g.:

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; } 

so the only way to observe a RetentionPolicy.CLASS annotation is by using a bytecode parser.

Another difference is that the Retention.CLASS annotated class gets a RuntimeInvisible class attribute, while Retention.RUNTIME annotations get a RuntimeVisible class attribute. This can be observed with javap.

Examples on GitHub for you to play with.