12.1.05

Annotations in Java (1.5)

Annotations have been introduced to Java officially by the JSR 175. Previously they were most known by XDoclet, IMO.

There have been many blogs and articles on the subject, but I will explain annotations from my point of view and assembles some resources you can find at the end of my blog entry. I took some information from the SUN article (although I wrote this entry before the article has been available at that URL).

Purpose of Annotations in Java

The motivation for the introduction of annotations into the Java programming language was the need for semantic information for a given piece of code. Normally, I would speak of entities as an annotation could also be applied to an application as a whole in the form of a descriptor. But the latter is only part of my imagination and not explicitely specified within the JSR 175, AFAIK.
Annotations in Java need to be well-defined. The reason is quite obvious: A compiler or another tool scanning a source code should be able to automatically process the semantic information applied by a programmer.

Declaration of Annotations

To ensure well-defined annotations and allow reusability of definitions made before, the JSR 175 defines two modelling entities: Annotation types and annotations. Annotations are based on annotation types and cannot exist without them.

Annotation Types

An annotation type will be defined like as it were a Java interface. That means you handle them like you did with a Java interface (with restrictions).
An annotation type class implicitely extends the marker interface java.lang.annotation.Annotation. But it may not extend other annotation types or other interfaces. The latter would not make much sense.
How can we distinguish between normal interface definitions and annotation type definitions? An annotation type is defined by using the @interface keywords (plural!) instead of interface. The "keywords" @ and interface are concatenated to result in @interface. You could separate them by a whitespace. But this is not encouraged by matter of style, as the JSR 175 writes.

A declaration of an annotation type could look like this (example taken from JSR 175):

// Normal annotation type declaration with several elements

/**
* Describes the "request-for-enhancement" (RFE)
* that led to the presence of
* the annotated API element.
*/
public @interface RequestForEnhancement {
int id(); // Unique ID number associated with RFE
String synopsis(); // Synopsis of RFE
String engineer(); // Name of engineer who implemented RFE
String date(); // Date RFE was implemented
}

As you can see the declaration contains four fields. It would be possible to leave out the parameter definitions. Then we would have a marker annotation type. As with a marker interface like java.lang.Serializable a tool could interpret an annotation based on a marker annotation type in a special way.

Annotations based on Annotation Types

As said, an annotation is based on an annotation type. We could say, it extends the annotation type interface and, with that, implements it. Finally we would not speak of implementation in the context of annotations, because they don't represent an executable statement in native java code.
An annotation is used similar to Javadocs. Javadocs are dedicated types of comments. They begin with the at-symbol @ and are included within a comment section surround by /* and */. But annotations are more than comments. You don't surround them with comment markers as this is the case with Javadoc. You just take the at-symbol, write the name of the annotation type to use after it, provide all parameters of the type with values and place the whole annotation just ahead of a program element to be annotated. Let's have a closer look at this and go into an example for clarification.

Usage of Annotations

The JSR 175 writes, that "annotation type declarations are legal wherever interface declarations are legal, and have the same scope and accessibility.".
With that in mind and the concept of annotations at hand for implementing annotation types, we can use annotations as a well-defined mechanism to "comment" on program elements.
Example of an annotation (taken from the JSR):

// Normal annotation
@RequestForEnhancement(
id = 2868724,
synopsis = "Provide time-travel functionality",
engineer = "Mr. Peabody",
date = "4/1/2004"
)
public static void travelThroughTime(Date destination) { ... }


The scope of the above annotation is a method named travelThroughTime. As you can discover the parameters defined within the annotation type RequestForEnhancement (see example in section Annotation Types) are assigned with values. The order of the parameters equals the order of definition. This is not a must but proposed by the JSR.
The advantage of using the above annotation is that we have machine-processible information about a method, a variable declaration or a class. You could then use these pieces of information to check who has implemented how many methods, when the last change has appeared etc. The example is quite simple and you could criticize it easily in terms of usefulness. But use your imagination... XDoclet is sort of similar and is used extensively in the field of J2EE. Although there is some criticism about it, too, I won't dig into it right here.

It is also possible to use marker annotations. An example tells you all:

// Marker annotation
@Preliminary public class TimeTravel { ... }

The meaning of the @Preliminary annotation should be easy to follow.

Conclusions

Not having said very much about annotations because of several constraints, they seem a valid approach of handling metadata within source code. There should be no questioning about the usefulness of metadata. But the form of the JSR 175 approach could be reviewed. In my eyes, the proposal is quite easy to realize. IMO, it presents a concept being very abbreviate and handy.
Future considerations could cope with tool-support for annotations or how to use them pratically (e.g. in which package to declare them etc.).

Resources

No comments: