Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About the parameter defined in process(...) method of Processor interface

In javax.annotation.processing package there is a interface Processor in which there is a function:

/**
     * Processes a set of annotation types on type elements
     * originating from the prior round and returns whether or not
     * these annotation types are claimed by this processor.  If {@code
     * true} is returned, the annotation types are claimed and subsequent
     * processors will not be asked to process them; if {@code false}
     * is returned, the annotation types are unclaimed and subsequent
     * processors may be asked to process them.  A processor may
     * always return the same boolean value or may vary the result
     * based on chosen criteria.
     *
     * <p>The input set will be empty if the processor supports {@code
     * "*"} and the root elements have no annotations.  A {@code
     * Processor} must gracefully handle an empty set of annotations.
     *
     * @param annotations the annotation types requested to be processed
     * @param roundEnv  environment for information about the current and prior round
     * @return whether or not the set of annotation types are claimed by this processor
     */
    boolean process(Set<? extends TypeElement> annotations,
                    RoundEnvironment roundEnv);

The Java API AbstractProcessor implements above interface. Now I created my own processor class:

public class MyProcessor extends AbstractProcessor {
   ...
   @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {

        for (TypeElement annotation: annotations) {
            // How can I get the class of the annotation ?
        }
    }
}

My questions:

  1. The API doc tells me the annotations in the process function are

the the annotation types requested to be processed

Then, why is it with type TypeElement not java.lang.annotation.Annotation ? I get confused by this because I am not sure whether the annotations actually mean the elements that being annotated or the real annotations annotating elements.

  1. Because of my 1st question above, how can I get each annotation's class from the TypeElement?
like image 682
Leem.fin Avatar asked Sep 24 '19 14:09

Leem.fin


People also ask

What is annotation Processor in java?

"Annotation Processing" is a hook into the compile process of the java compiler, to analyse the source code for user defined annotations and handle then (by producing compiler errors, compiler warning, emitting source code, byte code ...). API reference: javax. annotation. processing (Java Platform SE 6).

What is a Processor method in java?

The Processor class consists of methods that are invoked by the Java Integration stage. When a job that includes the Java Integration stage starts, the stage instantiates your Processor class and calls the logic within your Processor implementations.

When a Processor is created which of the following methods of AbstractProcessor will be invoked before all other methods?

When a Processor is created, before any other methods are invoked, the init method of the AbstractProcessor will be invoked.

How does annotation processing work?

The annotation processing is done in multiple rounds. Each round starts with the compiler searching for the annotations in the source files and choosing the annotation processors suited for these annotations. Each annotation processor, in turn, is called on the corresponding sources.


1 Answers

There is a package javax.lang.model which follows a mirror-based design described in Mirrors: Design Principles for Meta-level Facilities of Object-Oriented Programming Languages. It's a greatly designed abstraction used in (but not limited to) the annotation processing framework.

  1. Then, why is it with type TypeElement not java.lang.annotation.Annotation?

    When you design a framework, it's important to keep it open (available for extension). You never know what future versions of the language will bring. You need to stay flexible assuming a new form of metadata may appear.

    I get confused by this because I am not sure whether the annotations actually mean the elements that being annotated or the real annotations annotating elements.

    It's "the real annotations annotating elements" since you are processing annotation types.

    for (TypeElement typeElement : annotations) {
        // it's likely the ElementKind.ANNOTATION_TYPE
        typeElement.getKind();
    
        // elements annotated with the annotation
        environment.getElementsAnnotatedWith(typeElement);
    }
    
  2. Because of my 1st question above, how can I get each annotation's class from the TypeElement?

    The TypeElement represents your annotation class.

To read:

  1. https://bracha.org/mirrors.pdf (it will take a lot of time to process)

  2. https://www.baeldung.com/java-annotation-processing-builder (it's a simple annotation processor)

  3. https://github.com/rzwitserloot/lombok/blob/master/src/core/lombok/core/AnnotationProcessor.java (it's a good practical example)

  4. The Javadoc of the package and the core classes such as Processor, AnnotatedConstruct, Element, TypeElement, TypeMirror.

like image 166
Andrew Tobilko Avatar answered Sep 23 '22 18:09

Andrew Tobilko