注释处理器 - 如何获取它正在处理的类

我正在尝试编写自定义安托化处理器。注释处理器将在编译时处理每个类文件以检查注释,但是我如何能够获得它当前正在处理的类?我只能在以下代码中获取类名。

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) {
        if(e.getKind()==ElementKind.CLASS) {
            String className= e.getSimpleName().toString();
            processingEnv.getMessager().printMessage( javax.tools.Diagnostic.Kind.WARNING,className, e); 
        }
     }
}

答案 1

您无法访问注释处理器正在处理的类,因为该类尚未编译。相反,Java提供了类似的Elements api,用于输入源的反射式检查。

元素(您通过使用 找到的)包含有关正在编译的类的更多信息,而不仅仅是其名称。通过使用ElementVisitors可以找到大量有用的信息:roundEnv.getRootElements()

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
             }
        }
    }
}

答案 2
  1. 这不是注释处理的工作方式。在处理过程中无法获取对象,因为要定义的类正在编译中!如果你调用一个未知的类或使用,你会得到一个完全没问题。Class<?>getClass()Class<?> clazz = Class.forName("com.your.fancy.Class")java.lang.ClassNotFoundException
  2. 您需要使用诸如 和 之类的类来描述/读取类定义。javax.lang.model.element.Elementjavax.lang.model.element.ExecutableElement
  3. javax.lang.model.type.TypeMirror来描述类,它们的字段,方法等。javax.lang.model.*
  4. 如果您需要更多见解,只需包含来自java编译器(JAVA SDK)的工具.jar,即可获得更多在编译期间使用的类型定义。但最有可能的是 - 你不需要添加这个jar依赖关系!
  5. 你会得到即使这是真的。ClassNotFoundExceptionroundEnvironment.processingOver()
  6. 简而言之:在要使用类类型的所有位置使用TypeMirror

例子:

  • 从类中获取方法列表:
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;
}

推荐