Prior to Java 1.5 a TagInterface would have been used to mark a class as having some property - i.e. the interface is being used as MetaData.
JavaAnnotations provide a more comprehensive way of providing this MetaData so that it is more useful to the programmer.
The first notable difference is that annotations can be parameterised. For example the annotation @Retention is used to annotate other annotations and is parameterised by an enumeration. So you can have
@Retention(RetentionPolicy.RUNTIME)
Which, as it retains the annotation data at runtime, allows the programmer to find out about applied annotations using reflection, hence becoming the Java 1.5 basis of a TagInterface. The alternative would be to have a family of interfaces.
The second difference is that annotations can mark other things apart from just classes. The @Target annotation is used to do this thusly:
@Target(ElementType.METHOD)
Which would annotate an annotation as being valid for methods only. (The @Target annotation actually takes an array of ElementType but Java 1.5 provides some SyntacticSugar to hide that here).
An example use of the above two annotations would be for a UnitTesting framework. In JavaUnit methods that begin with 'test' are run as tests - but this can be a bit ugly. (See AnnotationsOverNamingConventions). With annotations we can tag a method thusly.
First we need to create our @Test annotation:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test {},
Then we tag our test methods:
public class MyTests {
@Test void myTest() {
},
},
Finally we use reflection to get our test methods:
public class TestRunner {
public static void runTests(Class c) throws Exception {
Object instance = c.newInstance();
for (Method m: c.getMethods()) {
if (m.getAnnotation(Test.class) != null) {
m.invoke(instance, new Object[]{},);
},
},
},
},
The advantages of annotations over tags are therefore:
- Annotations explicitly express the intent of the marker, instead of hijacking another language feature to use as reflective metadata.
- Annotations can target more than just types
- Annotations can be parameterised
The disadvantages are:
- Annotations can only be used in Java 5
- It takes more work to define an annotation than to define an empty interface
Category: JavaIdioms