How do different retention policies affect my annotations?

JavaAnnotations

Java Problem Overview


Can anyone explain in a clear way the practical differences between the java.lang.annotation.RetentionPolicy constants SOURCE, CLASS, and RUNTIME?

I'm also not exactly sure what the phrase "retaining annotation" means.

Java Solutions


Solution 1 - Java

> - RetentionPolicy.SOURCE: Discard during > the compile. These annotations don't > make any sense after the compile has > completed, so they aren't written to > the bytecode.
> Example: @Override, @SuppressWarnings > > > - RetentionPolicy.CLASS: Discard during > class load. Useful when doing > bytecode-level post-processing. > Somewhat surprisingly, this is the > default. > > - RetentionPolicy.RUNTIME: Do not > discard. The annotation should be > available for reflection at runtime. > Example: @Deprecated

Source: The old URL is dead now hunter_meta and replaced with hunter-meta-2-098036. In case even this goes down, I am uploading the image of the page.

Image (Right Click and Select 'Open Image in New Tab/Window') Screenshot of Oracle website

Solution 2 - Java

According to your comments about class decompilation, here is how I think it should work:

  • RetentionPolicy.SOURCE: Won't appear in the decompiled class

  • RetentionPolicy.CLASS: Appear in the decompiled class, but can't be inspected at run-time with reflection with getAnnotations()

  • RetentionPolicy.RUNTIME: Appear in the decompiled class, and can be inspected at run-time with reflection with getAnnotations()

Solution 3 - Java

Minimal runnable example

Language level:

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.SOURCE)
@interface RetentionSource {}

@Retention(RetentionPolicy.CLASS)
@interface RetentionClass {}

@Retention(RetentionPolicy.RUNTIME)
@interface RetentionRuntime {}

public static void main(String[] args) {
    @RetentionSource
    class B {}
    assert B.class.getAnnotations().length == 0;

    @RetentionClass
    class C {}
    assert C.class.getAnnotations().length == 0;

    @RetentionRuntime
    class D {}
    assert D.class.getAnnotations().length == 1;
}

Bytecode level: using javap we observe that the Retention.CLASS annotated class gets a RuntimeInvisible class attribute:

#14 = Utf8               LRetentionClass;
[...]
RuntimeInvisibleAnnotations:
  0: #14()

while Retention.RUNTIME annotation gets a RuntimeVisible class attribute:

#14 = Utf8               LRetentionRuntime;
[...]
RuntimeVisibleAnnotations:
  0: #14()

and the Runtime.SOURCE annotated .class does not get any annotation.

Examples on GitHub for you to play with.

Solution 4 - Java

Retention Policy: A retention policy determines at what point an annotation is discarded. It is s specified using Java's built-in annotations: @Retention[About]

1.SOURCE: annotation retained only in the source file and is discarded
          during compilation.
2.CLASS: annotation stored in the .class file during compilation,
         not available in the run time.
3.RUNTIME: annotation stored in the .class file and available in the run time.

Solution 5 - Java

  • CLASS :Annotations are to be recorded in the class file by the compiler but need not be retained by the VM at run time.
  • 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.
  • SOURCE :Annotations are to be discarded by the compiler.

Oracle Doc

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionxdevel2000View Question on Stackoverflow
Solution 1 - JavaFavoniusView Answer on Stackoverflow
Solution 2 - JavaewernliView Answer on Stackoverflow
Solution 3 - JavaCiro Santilli Путлер Капут 六四事View Answer on Stackoverflow
Solution 4 - JavaFerdous WahidView Answer on Stackoverflow
Solution 5 - JavaMichael WongView Answer on Stackoverflow