Yes, that is in fact the most basic and simple mode that you'd use an annotation processor in.
Any given annotation processor registers which annotations it is interested in. You can choose to say "*"
, in which case your annotation processor is handed every generated class model (that's the object representing a class in flight; after it has been parsed, but before it has been written to disk). More usually, you choose one or a few annotations, in which case you get notified only with those models that were annotated with one of these annotations:
Base project
MyAnno.java
package com.foo;
@Target(ElementType.TYPE) //[1]
@Retention(RetentionPolicy.SOURCE)
public @interface MyAnno {}
MyProcessor.java
@SupportedAnnotationTypes("com.foo.MyAnno") // [2]
class MyProcessor extends AbstractProcessor {
@Override public boolean process(Set<? extends TypeElement> annos, RoundEnvironment round) {
for (TypeElement annoType : annos) {
Set<? extends Element> annotatedElems = round.getElementsAnnotatedWith(annoType);
for (Element elem : annotatedElems) hello(elem);
}
return false;
}
private void hello(Element elem) {
// 'elem' can represent packages, classes, methods, fields, etc.
// because you constrainted the anno to only be allowed on types,
// it'd have to be a type (class or interface), so we can cast..
TypeElement typeElem = (TypeElement) elem;
// do whatever you want with it, here.
}
[1] this says that this annotation can only be put on types. So, for example, not on methods (trying to write @MyAnno public String foo() {}
would be a compiler error, stating that @MyAnno
cannot be placed on methods).
[2] There's a chicken-and-egg thing going on with annotation processors: You're still compiling code, which means the class files that represent the code possibly do not exist yet, nor does the compiler have a good idea on what methods are even available in them. Therefore, you do not get to use the usual reflection library. Instead, you get model/element types, such as TypeElement
, and a lot of it is 'stringly typed' where you refer to things in string form, such as here. The fact that you don't write @SupportedAnnotationTypes(MyAnno.class)
is an intentional part of the AP design.
Really, just follow your garden variety 'how do I write an annotation processor' tutorial. They should cover this.