如何使用“javax.lang.model.element.ElementVisitor”?
我尝试使用java注释处理器,并试图了解javax.lang.model中类的用法。就我所读到的内容而言,我认为ElementVisitor是使用模型的主要方式。但我不知道如何正确使用它 我知道访客的模式。到目前为止,我一直使用它来避免迭代元素的子元素和子元素的子元素。。。并避免测试的丑陋瞬间。但这位来访者似乎有所不同。如果我对模型元素调用accept,它不会访问子元素,而只访问元素本身 是否有人可以就如何使用API提供帮助 我找到了以下链接:。但是一个访客在另一个访客在另一个访客里面。。。只是感觉不对劲 编辑:为了更容易理解这个问题,我从上面的链接复制了代码。下面的代码似乎不正确。我不敢相信官方的JavaAPI是这样设计的。但是如何正确使用ElementVisitor呢如何使用“javax.lang.model.element.ElementVisitor”?,java,annotations,Java,Annotations,我尝试使用java注释处理器,并试图了解javax.lang.model中类的用法。就我所读到的内容而言,我认为ElementVisitor是使用模型的主要方式。但我不知道如何正确使用它 我知道访客的模式。到目前为止,我一直使用它来避免迭代元素的子元素和子元素的子元素。。。并避免测试的丑陋瞬间。但这位来访者似乎有所不同。如果我对模型元素调用accept,它不会访问子元素,而只访问元素本身 是否有人可以就如何使用API提供帮助 我找到了以下链接:。但是一个访客在另一个访客在另一个访客里面。。。只是
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);