Java-обработчик аннотации - получить родительский класс аннотированного элемента [duplicate]

6
задан falsetru 3 August 2013 в 16:58
поделиться

2 ответа

Вы не можете получить доступ к классу, обработанному обработчиком аннотации, потому что класс еще не скомпилирован. Вместо этого Java предлагает аналогичные элементы api для проверки стиля отображения источника.

Элемент (который вы нашли с помощью roundEnv.getRootElements()) имеет гораздо больше информации о компилируемом классе, чем просто его имя. Много полезной информации можно найти с помощью ElementVisitors:

http://docs.oracle.com/javase/6/docs/api/javax/lang/model/element/ElementVisitor .html http://docs.oracle.com/javase/6/docs/api/javax/lang/model/util/ElementKindVisitor6.html

Включая конструкторы классов, методы, поля и т. д.

Вот как это использовать:

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

         Set<? extends Element> rootE=roundEnv.getRootElements();
         for(Element e: rootE) {
             for(Element subElement : e.getEnclosedElements()){
                 subElement.accept(new ExampleVisitor(), null); // implement ExampleVisitor
             }
        }
    }
}
7
ответ дан John Ericksen 26 August 2018 в 05:48
поделиться
  1. Это НЕ, как работает AnnotationProcessing. Вы не можете получить объект Class<?> во время обработки, потому что классы, которые вы хотите, должны быть скомпилированы прямо сейчас! Если вы вызываете getClass() в неизвестном классе или используете Class<?> clazz = Class.forName("com.your.fancy.Class"), вы получите java.lang.ClassNotFoundException, который полностью прекрасен.
  2. Вам нужно использовать классы, такие как javax.lang.model.element.Element и javax.lang.model.element.ExecutableElement, чтобы описать / читать определения классов.
  3. javax.lang.model.* имеет javax.lang.model.type.TypeMirror для описания классов, их полей, методов и т. д.
  4. Если вам нужно больше проницательности, просто включите tools.jar из java-компилятора (JAVA SDK ), чтобы получить больше определений типов, которые используются во время компиляции. Но, скорее всего, вам не нужно добавлять эту зависимость jar!
  5. Вы получите ClassNotFoundException даже после того, как roundEnvironment.processingOver() будет правдой.
  6. IN SHORT: USE ТипMirror в все места, где вы хотели использовать тип класса.

Примеры:

  • получить список методов из класса:
public static @Nonnull List getMethods(@Nonnull Element annotationElem, @Nonnull RoundEnvironment roundEnvironment) {
    List outList = new ArrayList();

    String simpleName = annotationElem.getSimpleName().toString();
    for (Element elem  : roundEnvironment.getRootElements())
        if (elem.getSimpleName().toString().equals(simpleName))
            for (Element methodDeclaration :elem.getEnclosedElements())
                if (methodDeclaration instanceof ExecutableElement)
                    outList.add((ExecutableElement)methodDeclaration);

    return outList;
}
  • Получить имя метода из объявления метода:
public static TypeMirror getMethodFirstParam(@Nonnull ExecutableElement method, int n) {
     List parameters = ((ExecutableElement) method).getParameters();
     if (parameters != null && parameters.size() > 0)
         return parameters.get(n).asType();
     return null;
}
5
ответ дан kosiara - Bartosz Kosarzycki 26 August 2018 в 05:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: