Search code examples
javaannotations

How to verify that an annotation is only used on certain classes?


Say I have an annotation @Annotate and a class A. How can I check whether @Annotate is used on class A and its subclasses only (probably at compile time)?

So, if we have:

/* Example 1 */

public class A {

}  

public class B extends A {

}

public class C {

}

How do I check that class A and class B can be annotated by @Annotate but class C is not allowed (and might raise a compile error).


If we go with the decision that this would be checked at compile time:

/* Example 2 */

public class A {

}  

@Annotate
public class B extends A {

}

Example 2 will not raise a compile time error because @Annotate is used on a subclass of A. Example 3, however, will raise an compile error because @Annotate is not used on a subclass of A.

/* Example 3 */

@Annotate
public class C {

}

However, this does not have to be checked at compile time in anyway. I just personally thought that it makes sense to do so.


Solution

  • You should write an annotation processor. An annotation processor can generate new Java files and, more relevantly for your case, issue compile-time warnings.

    You will invoke it at compile time by running the java compiler like this: javac -processor MyProcessor MyFile.java. If regular javac or your annotation processor issues any warnings, then compilation fails.

    Your annotation processor's logic is specific to your @Annotate annotation and is simple: permit the annotation only on classes that subclass A. There are various tutorials on the web about how to write an annetation processor, in addition to the Oracle documentation I linked above.