Annotations

As we mentioned in , Java for a long time has supported a limited kind of metadata in Java source code through the use of Javadoc comment tags. With Javadoc tags like @deprecated or @author, we can add some information to a class, method, or field. In this case, the information is mainly useful to the Javadoc documentation generator, because comments exist only in Java source code. However, developers have long wanted a way to generalize metadata for other purposes. And in fact, some tools have been developed over the years that read extended Javadoc-style tags in comments and do all sorts of things with them, including code generation and documentation. In Java 5.0, a new formal, extensible metadata system called annotations has been added to the language that provides the Javadoc-style, source-level functionality as well as new possibilities for using metadata at runtime. Annotations allow you to add metadata to Java classes, methods, and fields. This metadata can be utilized by tools at compile time and optionally retained in the compiled Java classes for use at runtime as well. The availability of annotation data to the running program opens up new uses for metadata. For example, annotations cannot only be used at compile time to generate auxiliary classes or resources but also could be used by a server to provide special services to classes such as importing or exporting of values, security, or monitoring. Annotations will be used heavily in the Enterprise JavaBeans (EJB) Version 3 specification to simplify configuration and deployment information. Technically, according to the spec, annotations are not supposed to "directly affect the semantics of a program." However, that admonition is a little vague and there is some fear in the Java community that this facility will open a Pandora's box of possible abuses. Hopefully, developers will use them with restraint. Only a handful of "built-in" annotations are supplied with Java 5.0 and we'll summarize them in this section. Creating new annotations is syntactically easy, but implementing the behavior for them (via the compiler or a runtime system) is a bit beyond the scope of this tutorial, so we won't cover that here. The Sun JDK provides a framework tool called apt that can be used to implement source-level annotations that generate and compile code or resource files. Accessing annotation data at runtime is done via the Reflection API as described earlier in this chapter.

Using Annotations

The @Deprecated annotation is an example of the simplest kind, a marker or flag annotation. A marker annotation indicates some semantics just by its presence. (In the case of @Deprecated it means that the member is deprecated and the compiler should generate warnings if it is used.) To use the @Deprecated annotation, we place it before a Java class, method, or field like this:

 @Deprecated class OldClass { ... }
 class AgingClass {
 @Deprecated public someMethod( ) { ... }
 ...
 }


More generally, annotations may take "arguments" in an extended method-like syntax. Table 7-1 summarizes the possible variations.

Table 7-1. Use of arguments in annotations

Example

Description

@Deprecated

Marker annotation (no "data")

@WarningMessage("Something about...")

Single argument

@TestValues( { "one", "two" } )

Array of arguments

@Author( first="Pat", last="Niemeyer" )

Named arguments


(The first annotation in the table, @Deprecated, is a real annotation as described earlier; the remaining three are fictitious.) To accept multiple values, an annotation may either use the curly brace ({}) array syntax or the more novel named argument syntax listed in the final example. The named syntax allows arguments to be passed in any order.

Standard Annotations

Table 7-2 summarizes the app-level standard annotations supplied with Java 5.0.

Table 7-2. Standard annotations

Annotation

Description

@Deprecated

Deprecation warning on member

@Override

Indicates that the annotated method must override a method in the parent class or a compiler warning is issued

@SuppressWarnings(value="type")

Indicates that the specified warning types should be suppressed by the compiler for the annotated class or method


We have already discussed the @Deprecated and @Override annotations, the latter of which we discussed in the section "Overriding Methods" in . The @SuppressWarnings annotation is intended to have a compelling use in bridging legacy code with new generic code in Java 5.0, but at the time of this writing, it is not implemented. Technically, four other standard annotations are supplied with Java 5.0, but they are part of the java.lang.annotations package and are used to annotate only other annotations (they are really meta-annotations). For example, the java.lang.annotation.Retention annotation sets the retention policy for an annotation, specifying whether it is retained in the compiled class and loaded at runtime.

The apt Tool

The Java 5.0 JDK from Sun ships with the command-line Annotation Processing Tool, apt, that is a sort of frontend to the javac compiler. apt uses pluggable annotation processors to process the annotations in source files before the code is compiled by javac. If you write your own source-level annotations, you can build a plug-in annotation processor for apt that will be invoked to process your annotation in the source code. Your annotation processor can be quite sophisticated, examining the structure of the source code (in a read-only fashion) through the supplied syntax tree (object model) and generating any additional files or actions that it wishes. If you generate new Java source files, they will be automatically compiled by javac for you. Running apt on a source file with no annotations simply falls through to javac.

Java ScreenShot
Comments