Wednesday, June 8, 2011

Annotations in Java

After many years in the dark, I finally pulled myself together and started exploring this "new" feature called Annotations or meta-programming.

First things first - how to define an annotation.

The people behind Java is like the people behind the Porche 911 sports-car, incredibly lazy. Instead of coming up with a selfdescribing keyword, like Annotation, they just added a @ in front of the already known Interface keyword. So if you want to define your own Annotation you simply write this in your text-editor:

public @interface MyAnnotation  {} 
Now lets use our spanking new and incredibly awesome annotation on a new class:
@MyAnnotation
class MyClass {

}
It's that easy, just add @MyAnnotation in front of the class definition. It's also possible to use annotations on methods, which I'll demonstrate later on.

Next - adding data members to your annotation.

You could just use your annotation as flags, for instance you could create a Serializable Annotation and use this instead of the old Serializable Interface, like so:
public @interface Serializable {

}

@Serializable
public class SerializableClass {

}
This is all fine and dandy, but the purpose of annotations is to make metaprogramming possible, or at least easier. For that to work, we need to be able to define some data that goes along with our annotations. You define the data by adding one or more declarations, using this syntax: datatype nameOfMetadData followed by () and a default value using the default keyword with the desired value behind it. Here are some examples:
public @interface MyAnnotation {
int someID();
String someMetaDataAsString();
double someDoubleMetaDataWithDefaultValue() default 1234;
}

public @interface MySecondAnnotaion {
String value();
}
Annotations are only allowed to return: primitive types, Strings, Enums and arrays which contains the preceding types


It's important to remember, that annotations should only be used to describe things about a object that is outside or irrelevant to the business domain, that the object is part of. For instance, imagine a Person object that is annotated with a PersonDetail annotation, that describes stuff like the persons name, address and so on. Theses "info" are not metadata and are relevant to the domain, and should therefore be members of the object. Annotations should be used to describe stuff like how to map a given object to a database table (JPA annotations), or how a service might need transaction-handling, which are then inspected by some application framework.

If you need to read annotations programmatically take a look at JSR-269 http://www.jcp.org/en/jsr/detail?id=269

No comments: