Search code examples
javareflectionannotationsannotation-processingjava-annotations

Get Class fields from annotated Object in annotation processor


i'm working on my first annotation processor. I'm trying to get fields of class through annotation on declared object(that is a field of a method). For example:

public class Person {
    private String name;
    private String surname;
}

...
public void myMethod(@MyAnnotation Person person) { 
    /*...*/
}
...

Through @MyAnnotation i want to get 'name' and 'surname' fields.

Is that possible? I did something of similar with method's field:

...
for (Element element : roundEnvironment.getElementsAnnotatedWith(AnnotationOnMethod.class)) {
    ExecutableElement method = (ExecutableElement) element;
    List<? extends VariableElement> parameters = method.getParameters();
    parameters.forEach(p -> {
        /*code here for parameter*/
    });
}
...

Thanks in advance, Luca.

Solution: For my solution i am assuming that the annotation is on method and not on method's parameter. The correct answer to my question is the answer posted by rjeeb. You can see it below.


Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(AnnotationOnMethod.class);
for (Element element : elements) {
    ExecutableElement executableElement = (ExecutableElement) element; 
    List<? extends VariableElement> parameters = executableElement.getParameters();
    for (VariableElement parameter : parameters) {
        DeclaredType declaredType = (DeclaredType) parameter.asType();
        TypeElement clazz = (TypeElement) declaredType.asElement();
        clazz.getEnclosedElements().forEach(o -> {
                if (o.getKind().isField()) {
                    log.info("Simple name of field: " + o.getSimpleName());
                }
        });
    }
}

Solution

  • Your annotation is of type ElementType.PARAMETER so once you get the element that annotated with it then it should be TypeElement and therefore you can get the fields of this type element

    for (Element element : roundEnv.getElementsAnnotatedWith(AnnotationOnMethod.class)) {
        TypeElement typeElement = elementUtils.getTypeElement(element.asType().toString());
        Set<? extends Element> fields = typeElement.getEnclosedElements()
                .stream()
                .filter(o -> o.getKind().isField())
                .collect(Collectors.toSet());
    
        // do something with the fields
    }
    

    you can get the helper classes from the AbstractProcessor

    private Messager messager;
    private Types typeUtils;
    private Elements elementUtils;
    
    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        messager = processingEnv.getMessager();
        typeUtils = processingEnv.getTypeUtils();
        elementUtils = processingEnv.getElementUtils();
    }