Composing Java annotations
The allowed attribute types of a Java annotations are deliberately very restrictive, however some clean composite annotation types are possible with the allowed types.
Consider a sample annotation from the tutorial site:
package annotation;
@interface ClassPreamble {
String author();
String[] reviewers();
}Here the author and reviewers are of String and array types which is in keeping with the allowed types of annotation attributes. The following is a comprehensive list of allowed types(as of Java 7):
- String
- Class
- any parameterized invocation of Class
- an enum type
- an annotation type, do note that cycles are not allowed, the annotated type cannot refer to itself
- an array type whose element type is one of the preceding types.
Now, to make a richer ClassPreable consider two more annotation types defined this way:
package annotation;
public @interface Author {
String first() default '';
String last() default '';
}
package annotation;
public @interface Reviewer {
String first() default '';
String last() default '';
}With these, the ClassPreamble can be composed from the richer Author and Reviewer annotation types, this way:
package annotation;
@interface ClassPreamble {
Author author();
Reviewer[] reviewers();
}Now an annotation applied on a class looks like this:
package annotation;
@ClassPreamble(author = @Author(first = 'John', last = 'Doe')
, reviewers = {@Reviewer(first = 'first1', last = 'last1'), @Reviewer(last = 'last2') }
)
public class MyClass {
....
}This is a contrived example just to demonstrate composition of annotations, however this approach is used extensively for real world annotations, for eg, to define a many to many relationship between two JPA entities:
@ManyToMany
@JoinTable(name='Employee_Project',
joinColumns=@JoinColumn(name='Employee_ID'),
inverseJoinColumns=@JoinColumn(name='Project_ID'))
private Collection<Project> projects;
Reference: Composing Java annotations from our JCG partner Biju Kunjummen at the all and sundry blog.

