Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the reason for java.lang.annotation.Retention?

I'm well aware about the meaning of the RetentionPolicy and know what they do and when it seems to make sense to use them. For my own annotation, I exactly know if they're needed at runtime, in class files, or just for the compilation. However, with any annotation defined in a library, you can IMHO never be sure.

For example, javax.annotation.Generated is meant to mark generated code, but it's rarely useful. As there are AFAIK more tools working on the bytecode than tools working with the source, the information disappears just before it could be used.

As annotations absent at runtime don't throw ClassNotFoundException (unlike e.g., missing interfaces), using RetentionPolicy.RUNTIME seems to cause no harm. Or am I wrong?

Or was the saving of a few bytes the reason for using different Retentions? To me it seems to cause too many problems to be worth it. What am I missing?

like image 293
maaartinus Avatar asked May 06 '16 04:05

maaartinus


People also ask

What is retention annotation in Java?

java.lang.annotation.Retention. Indicates how long annotations with the annotated type are to be retained. If no Retention annotation is present on an annotation type declaration, the retention policy defaults to RetentionPolicy. CLASS .

What is the purpose of annotation in Java?

Annotations are used to provide supplemental information about a program. Annotations start with '@'. Annotations do not change the action of a compiled program. Annotations help to associate metadata (information) to the program elements i.e. instance variables, constructors, methods, classes, etc.

What is the use of @interface annotation?

The @interface element is used to declare an annotation. For example: @interface MyAnnotation{}

What is @deprecated annotation in Java?

@Deprecated @Deprecated annotation indicates that the marked element is deprecated and should no longer be used. The compiler generates a warning whenever a program uses a method, class, or field with the @Deprecated annotation.


1 Answers

The inspiration for Java Annotations occurred before 2002, around the transition from Java 1.3 to Java 1.4. A high spec desktop in those days was a Pentium 4 at about 2.5GHz or an Athlon XP+ at around 2GHz, RAM would be 256 or 512MB. Eg a review here.

The problem was how to store and retrieve metadata about the code. The typical solution was by using XML files that were not type-checked or directly linked to the source code. Others were already informally extending JavaDoc (the source code and extension API was present in the JDK) for code generation tools. The solution, Annotations, is hack (a pretty darn good hack) that extended Javadoc and the JLS Class specification.

It's clear the original authors were worried about performance (and in 2002, Java was still relatively slow, reflection very slow and the Java runtime was an enormous memory hog; some things never change). This is from the introduction to JSR-175:

Since many annotations will be used only by development tools such as stub generators, it makes little sense to retain all annotations at run time; doing so could increase run-time memory-footprint and harm performance. There are, however, some annotation types that are useful at run time, and some that are useful in tools that only have access to class files (not source files). Therefore, certain annotations are stored by the compiler in class file attributes (JVMS 4.7), and some of these annotations are then made available for inspection at runtime via new reflective APIs.

Their solution to the problem was to divide the problem into three use cases:

VI. Reading annotations

Annotation consumers may be divided into three groups:

a. "Introspectors" - Programs that query runtime-visible annotations of their own program elements. These programs will load both annotated classes and annotation interfaces into the virtual machine. (By runtime-visible, we mean annotations whose retention policy is RUNTIME.)

b. "Specific Tools" - Programs that query known annotation types of arbitrary external programs. Stub generators, for example, fall into this category. These programs will read annotated classes without loading them into the virtual machine, but will load annotation interfaces.

c. "General Tools" - Programs that query arbitrary annotations of arbitrary external programs (such as compilers, documentation generators, and class browsers). These programs will load neither annotated classes nor annotation interfaces into the virtual machine. Such programs are said to operate "at arm's length."

This allowed the (at that time) significant use cases of "specific tools" and "general tools" as defined above to do their thing without creating a burden on the runtime; for these tools, annotations could either be SOURCE or CLASS. Only annotations that were needed at runtime (from the above, it's clear this is was considered the minority use case) would be loaded and retained in the JVM.

So, yes, the retention policy was put in place to save bytes and runtime overhead. While this looks quaint now, 2002 was a different world and memory and performance were very real concerns. Now we have 10x performance and memory, you can safely use RUNTIME retention without concern.

like image 112
Andrew Alcock Avatar answered Nov 10 '22 10:11

Andrew Alcock