Java annotations


Creative Commons License
This Java annotations tutorial is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License
Preamble
This tutorial is a concise presentation about the notion of annotation that has been introduced in Java from Java 5.
Resource
Annotations.Java.zip 
Characterization
The notion of annotation is an additional notion to the previous notions of class and interface. Java annotations may be (incompletely) compared to C++ compilation macro-statements, for instance:
#ifndef _symbol
#define _symbol
…
#endif
However, Java annotations have higher scope and power than C++ macro-statements since they may persist and be used at run-time (java.lang.reflect API).

Sample

An annotation can be defined as follows:
public @interface Copyright { // Please note the '@' just before 'interface'!
    char[] codes() default {'\u00AE','\u00A9','\u2122'};
    String author() default "Franck Barbier";
} 

Rules

Interesting capabilities: default values for properties may be setup by means of the default keyword.

What is the purpose of Java annotations?

Java annotations mainly serve as markers for the Java code in order to be interpreted at compilation time, at deployment time and at run-time, for example (run-time usage):
@Copyright(codes = {'\u2122'},author = "Anonymous")
public class My_class {
    public static void main(String[] args) {
        java.lang.annotation.Annotation annotations[] = (new My_class()).getClass().getAnnotations(); // Access by introspection
        for(int i = 0;i < annotations.length;i++) System.out.println("Annotation #" + i + ": " + annotations[i].toString());
    }
}
Display:
Annotation #0: @com.FranckBarbier.Java._Annotations.Copyright(author=Anonymous, codes=[™])
Existing (core) annotations
In Java SE and Java EE frameworks (from Java SE 5 and Java EE 5), many predefined annotations exist. The seven core annotations are:

@java.lang.annotation.Target

This annotation has a unique property (named value) of type array of java.lang.annotation.ElementType with the following possible values:

@java.lang.annotation.Retention

This annotation has a unique property (named value) of type array of java.lang.annotation.RetentionPolicy with the following possible values: Current definition (Java 8 API) -> here
@Documented
@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@Target(value = java.lang.annotation.ElementType.ANNOTATION_TYPE)
public @interface Retention {
    java.lang.annotation.RetentionPolicy value() default java.lang.annotation.RetentionPolicy.CLASS;
}
Revisiting the user-defined @Copyright annotation
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target({java.lang.annotation.ElementType.PACKAGE,java.lang.annotation.ElementType.TYPE})
public @interface Copyright { …
Resource injection

Definition

@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.TYPE,java.lang.annotation.ElementType.FIELD,java.lang.annotation.ElementType.METHOD})
public @interface Resource { …

Usage

@javax.annotation.Resource
private javax.transaction.UserTransaction _utx; // No instantiation required!
Annotating a method parameter
Defining the annotation itself:
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(value = java.lang.annotation.ElementType.PARAMETER)
public @interface May_be_null { }
Using it:
public void foo(@May_be_null Object o) { … }
Annotation inheritance
Annotations may be inherited provided that they are declared as inheritable, example:
@java.lang.annotation.Inherited
public @interface Copyright { …
My_class is already annotated with @Copyright while Another_class inherits from My_class:
public class Another_class extends My_class { …
Testing inherited annotations
Declared annotations…:
java.lang.annotation.Annotation other_annotations[] = (new Another_class()).getClass().getDeclaredAnnotations();
for(int i = 0;i < other_annotations.length;i++) System.out.println("Annotation #" + i + ": " + other_annotations[i].toString()); // Nothing is displayed!
… versus owned annotations:
java.lang.annotation.Annotation other_annotations[] = (new Another_class()).getClass().getAnnotations();
for(int i = 0;i < other_annotations.length;i++) System.out.println("Annotation #" + i + ": " + other_annotations[i].toString());
Display:
Annotation #0: @com.FranckBarbier.Java._Annotations.Copyright(author=Anonymous, codes=[™])