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:
Category: JavaIdioms