Annotations are to be recorded in the class file by the compiler but need not be retained by the VM at run time. 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. Annotations are to be discarded by the compiler.
SOURCE: Annotations will be retained at the source level and ignored by the compiler. CLASS: Annotations will be retained at compile-time and ignored by the JVM. RUNTIME: These will be retained at runtime.
Annotations have a number of uses, among them: Information for the compiler — Annotations can be used by the compiler to detect errors or suppress warnings. Compile-time and deployment-time processing — Software tools can process annotation information to generate code, XML files, and so forth.
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.
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')
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()
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With