如何使用“javax.lang.model.element.ElementVisitor”?

如何使用“javax.lang.model.element.ElementVisitor”?,java,annotations,Java,Annotations,我尝试使用java注释处理器,并试图了解javax.lang.model中类的用法。就我所读到的内容而言,我认为ElementVisitor是使用模型的主要方式。但我不知道如何正确使用它 我知道访客的模式。到目前为止,我一直使用它来避免迭代元素的子元素和子元素的子元素。。。并避免测试的丑陋瞬间。但这位来访者似乎有所不同。如果我对模型元素调用accept,它不会访问子元素,而只访问元素本身 是否有人可以就如何使用API提供帮助 我找到了以下链接:。但是一个访客在另一个访客在另一个访客里面。。。只是

我尝试使用java注释处理器,并试图了解javax.lang.model中类的用法。就我所读到的内容而言,我认为ElementVisitor是使用模型的主要方式。但我不知道如何正确使用它

我知道访客的模式。到目前为止,我一直使用它来避免迭代元素的子元素和子元素的子元素。。。并避免测试的丑陋瞬间。但这位来访者似乎有所不同。如果我对模型元素调用accept,它不会访问子元素,而只访问元素本身

是否有人可以就如何使用API提供帮助

我找到了以下链接:。但是一个访客在另一个访客在另一个访客里面。。。只是感觉不对劲

编辑:为了更容易理解这个问题,我从上面的链接复制了代码。下面的代码似乎不正确。我不敢相信官方的JavaAPI是这样设计的。但是如何正确使用ElementVisitor呢

tElem.accept(new SimpleElementVisitor6<Void, ...>() {
  public Void visitType(TypeElement e, ...) {
    for (Element tSubElem : e.getEnclosedElements()) {
      tSubElem.accept(new SimpleElementVisitor6<AssocEndSpec, ...>() {
        public AssocEndSpec visitExecutable(ExecutableElement ex, ...) {
          TypeMirror tRetTypeMirror = ex.getReturnType();
          tRetTypeMirror.accept(new SimpleTypeVisitor6<TypeElement, TypeElement>() {
            public TypeElement visitDeclared(DeclaredType t, TypeElement enclose) {
              for (TypeMirror tTypeArgMirror : t.getTypeArguments()) {
                tTypeArgMirror.accept(new SimpleTypeVisitor6<TypeElement, ...>() {
                  public TypeElement visitDeclared(DeclaredType t, TypeElement self) {
                    TypeElement tArgTypeElem = (TypeElement) t.asElement();
                    if (!self.equals(tArgTypeElem)) {
                      // found the little bugger!
                    }
                  }
                }, ...);
              }
            }
          }, ...);
        }
    }, ...);
  }
}, ...);
这代码是胡说八道

看看javax.lang.model.util.ElementKindVisitor6或javax.lang.model.util.ElementScanner6,它们可能会做什么。在任何情况下,您都应该能够获取他们的资源,并根据您的需要进行调整

注:话虽如此,我也要说ElementVisitor是一个相当奇怪的访问者实现。

我也有同样的问题,javax.lang.model.util.ElementScanner9就是我要找的。引用有关ElementScanner9 enphasis矿山的javdoc:

此类中的visitXYZ方法通过 调用其封闭元素、参数等的扫描,如 在单独的方法规范中指出

由于这些访问者实现的示例是internet上的scarse,因此我编写了以下代码使其工作问题是获取给定类的所有字段:


import java.util.ArrayList;
import java.util.List;

import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementScanner9;

/**
 * visitor which collects all the fields of a class
 * 
 * <pre>{@code
 *  TypeElement t = ...;
 *  List<VariableElement> fields = t.accept(new FieldElementVisitor(), null);
 * }</pre>
 *
 * @param <P>
 */
public class FieldElementVisitor<P> extends ElementScanner9<List<VariableElement>, P>{

    protected List<VariableElement> variables;

    public FieldElementVisitor() {
        super(new ArrayList<>());
        this.variables = this.DEFAULT_VALUE;
    }

    @Override
    public List<VariableElement> visitVariable(VariableElement e, P p) {
        if (isVariableAClassField(e)) { //to implement
            this.variables.add(e);
        }
        return this.variables;
    }

}
下面是我为使用它而编写的代码:

在上面的示例中,我不需要它,但是您可以自定义visitXYZ方法,并且仍然可以通过调用super.visitXYZ对其子对象调用visit方法,正如javadoc所说

当子类重写visitXYZ方法时,新方法可以 使用默认方式扫描封闭的元素 呼叫super.visitXYZ。通过这种方式,具体的访问者可以 使用控制组件元素的遍历顺序 关于附加处理


ElementScanner6是我要找的。尽管我仍然不确定如何处理其他实现。。。如果不遍历组合,它们似乎毫无用处。谢谢你的提示!
TypeElement classElement = ...;
List<VariableElement> fields = new FieldElementVisitor<Void>().visit(classElement);