Making the Most of Java 5: Annotations

Tagged:  

In this second in a series of articles on the new Java 5 language features, we'll cover annotations. Annotations are used to represent metadata in the Java language, a feature which comes in particularly handy when designing software frameworks, where some type of metadata is often needed to describe the interaction of client software with the container or framework in which it is running. In such a role, they often come into direct competition with the more traditional way of describing metadata with Java, XML.

First, an introduction.

Syntax and Usage

A new symbol is introduced into Java to handle annotations: the '@' character. It is used both in defining and declaring annotations. When defining an annotation, you use a new keyword, @interface. For example,

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
     public String name();
     //Let's assume they are clever...
     public boolean clever() default true;
}

As the keyword implies, annotations are a special type of interface. Here we have defined a new annotation with two properties, 'name' and 'clever'. The 'clever' property has a default value, which is true. This will be supplied if the annotation declaration does not provide a value for this property. The property (or method return types) defined by an annotation are restricted to: primitives, String, Class, annotations, enums, and arrays of these types. Note that there are two basic meta-annotations (annotations on annotations) supplied by Java: @Retention, which specifies at what stages the annotation information is kept, and @Target, which defines on what Java elements an annotation can be used. @Retention takes an enum, RetentionPolicy, that has the values:

CLASS - the annotation is retained in Java .class files but discarded at runtime
SOURCE - the annotation is discarded by the compiler
RUNTIME - the annotation is retained in the Java .class files and kept at runtime

@Target takes an array of an enum, ElementType, which specifies on which Java language elements the annotation can be used. These are:

ANNOTATION_TYPE - an annotation definition
CONSTRUCTOR - a Java type constructor declaration
FIELD - A class-level variable
LOCAL_VARIABLE - A variable declaration local to a block (e.g., a method)
METHOD - A class method
PACKAGE - A package declaration
PARAMETER - A parameter type declared by a Java method
TYPE - a Java class type definition

An annotation can then be used in Java source, like this:

public class MyClass {
     @MyAnnotation(name="Bob")
     public void doSomething() {
          //...
     }
}

Since this is defined as a RUNTIME annotation, it can be reflectively read from the class at runtime. An example might look like this:

public void readAnnotation(Class clazz) {
    MyAnnotation a = clazz.getMethod("doSomething")
          .getAnnotation(MyAnnotation.class);
    System.out.println(a.name() + " is clever? " + a.clever());
}

Vs. XML

Annotations are both very simple and, at the same time, powerful. They have redefined the way that many traditionally XML-based frameworks (EJB 3.0, JAXB, Spring) interact with client code. So what are the advantages or disadvantages of each?

1. XML is more verbose than annotations. Typically, in an XML metadata file, a substantial amount of the structure is dedicated to describing the Java object graph and how the metadata affects it. And verbosity is the natural enemy of readability...
2. XML is less type-safe. It is easy, and common, to mis-type a fully-qualified Java type in an XML file. Most of the time the framework does not check that the type is valid, and will wind up throwing a less-informative error somewhere down the line. Since it is much easier to know the type associated with an annotation (via reflection), this is not a problem. For the same reasons, annotations are much more "tool-friendly".
3. XML files can be more centralized, since they are not co-located with the source. This can be an advantage in certain situations where it is more natural to have the metadata in one place.
4. Annotations are faster. Parsing XML is slower than reflecting annotations, though by how much depends a lot on the situation. If this performance is merely a "startup cost" it may not be relevant at all.
5. Annotations are harder to use with third-party libraries. If you have third-party libraries, and you want to use metadata with those classes, you are out of luck unless the library is open-source. With XML, this is not a problem, because it is not as intrusive.

Some have stated that having annotations on Java source introduces coupling between the source and the metadata. This is not true. Annotations are entirely optional, and need not be read at all. The only potential snag is that having annotations on your source rather than using XML does introduce a stronger dependency on the library (-ies) that contain the annotations, since these must be on your classpath for compilation. But for many, this is not a serious issue.

Conclusion

In general, most framework authors have found that the benefits of annotations outweigh the downsides, and POJOs (Plain Old Java Objects) + Annotations have become the new paradigm in creating Java standards. This is not to say that XML has become obsolete by any means. XML has its place, and always will. But Java developers are certainly relieved by the fact that it is not the only option anymore. And framework writers are relieved that they do not need to parse XML just to get client metadata.

[...] In a series of articles Brennan Spies explores some of the Java 5 enhancements, generics, enums and annotations. [...]

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <pre> <div> <blockquote> <object> <embed> <img> <param>
  • Lines and paragraphs break automatically.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Copy the characters (respecting upper/lower case) from the image.