According to the Kotlin language spec, there are three types of annotation retention:
- Source retention (accessible by source-processing tools);
- Binary retention (retained in compilation artifacts);
- Runtime retention (accessible at runtime).
Looking at the KDoc for kotlin-stdlib on the JVM we get the following:
public enum class AnnotationRetention {
/** Annotation isn't stored in binary output */
SOURCE,
/** Annotation is stored in binary output, but invisible for reflection */
BINARY,
/** Annotation is stored in binary output and visible for reflection (default retention) */
RUNTIME
}
I can understand the use cases for SOURCE
(available for inspection by annotation processors) and RUNTIME
(available for inspection using reflection) but I cannot understand a use case for BINARY
.
Can someone please explain a use case for this type of retention? Why would I choose BINARY
over SOURCE
if I don't need RUNTIME
?
In Java, annotations are used to attach meta-data to a program element such as a class, method, instances, etc. Some annotations are used to annotate other annotations. These types of annotations are known as meta-annotations. @Retention is also a meta-annotation that comes with some retention policies.
Annotation with retention policy SOURCE will be retained only with source code, and discarded during compile time. Annotation with retention policy CLASS will be retained till compiling the code, and discarded during runtime. Annotation with retention policy RUNTIME will be available to the JVM through runtime.
Some annotations are used to annotate other annotations. These types of annotations are known as meta-annotations. @Retention is also a meta-annotation that comes with some retention policies. These retention policies determine at which point an annotation is discarded. There are three types of retention policies: SOURCE, CLASS, and RUNTIME.
In Java, annotations are used to attach meta-data to a program element such as a class, method, instances, etc. Some annotations are used to annotate other annotations. These types of annotations are known as meta-annotations.
Notice that each binary (2) is padded with a 0x00. And because we think of binary (2) as a string like char (2), that padding happens on the right of each part.
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. Here we will be creating three custom annotations with retention policies such as SOURCE, CLASS, and RUNTIME.
As per the comment by Alexey Romanov, there is a use case for annotations outside annotation processing and runtime reflection which is shown in the answers for Java Annotations - looking for an example of RetentionPolicy.CLASS
For instance, Proguard takes .jar
files and performs obfuscation and shrinking on them as per the diagram from the Proguard website below:
The @Keep
annotation tells Proguard not to remove a target during shrinking. This kind of annotation must be present in the binary since Proguard operates on .jar
files. Since @Keep
is not intended to be inspected at runtime using reflection, it would be a suitable use case for AnnotationRetention.BINARY
.
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