首页 > 解决方案 > 注释处理器中的元素类型不是来自 javax.lang.model.element 包

问题描述

我有注释解析器,在里面我使用这段代码:

        Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(annotation);
        for (Element el : annotatedElements) {
            try {
               TypeElement targetClass = (TypeElement) el;
               List<? extends VariableElement> fields = getFields(targetClass);
               for (VariableElement e : fields) {
                   String type = getType(e);
                   String name = getVariableName(e));                              
               }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

和方法:

public List<? extends VariableElement> getFields(TypeElement targetClass) {
    List<? extends Element> enclosedElements = targetClass.getEnclosedElements();
    List<VariableElement> fields = new ArrayList<>(enclosedElements.size());
    for (Element field : enclosedElements) {
        if (field.getKind() == ElementKind.FIELD && !field.getModifiers().contains(Modifier.STATIC)) {
            fields.add((VariableElement) field);
        }
    }
    return fields;
}


public String getType(VariableElement variable) {
    if (variable instanceof PrimitiveType) {
        return variable.asType().toString();
    }
    return ((DeclaredType) variable.asType()).asElement().toString();
}

第一个方法获取类中的所有非静态字段。

第二种方法应该获取变量的类型为String,如“String”、“boolean”、“MyObject”等。但是,当该字段是类型时,boolean我收到此错误:

com.sun.tools.javac.code.Type$JCPrimitiveType 不能转换为 javax.lang.model.type.DeclaredType

我希望布尔和其他原始类型是类型PrimitiveType但是由于某种原因它是com.sun.tools.javac.code.Type$JCPrimitiveType

同样,当我尝试从课堂上获取所有吸气剂时:

public List<? extends VariableElement> getGetterMethods(TypeElement targetClass) {
    List<? extends Element> enclosedElements = targetClass.getEnclosedElements();
    List<VariableElement> fields = new ArrayList<>(enclosedElements.size());
    for (Element field : enclosedElements) {
        if (field.getKind() == ElementKind.METHOD &&
                !field.getModifiers().contains(Modifier.STATIC) &&
                (field.getSimpleName().toString().startsWith("get") || field.getSimpleName().toString().startsWith("is"))) {
            fields.add((VariableElement) field);
        }
    }
    return fields;
}

我得到错误:

java.lang.ClassCastException:com.sun.tools.javac.code.Symbol$MethodSymbol 无法转换为 javax.lang.model.element.VariableElement

似乎com.sun.tools.javac.code包应该是 JDK 的一部分,但是我无论如何都找不到它。因此我无法导入它,也许会做一些调整。

处理此错误的最佳方法是什么?即使我可以导入包,它的类型似乎也被奇怪地分配了,因为我希望它的类型是javax.lang.model.element包的一部分。

感谢帮助!

//编辑

根据文档:

public static class Type.JCPrimitiveType
extends Type
implements PrimitiveType

所以 Type.JCPrimitiveType 应该是 instanceOf PrimitiveType,但由于if某种原因在执行时不成立

标签: javacompilation

解决方案


Element.getEnclosedElements() 将检索所有 Elements。而是尝试将您的更改getGetterMethods(TypeElement)为:

...
import javax.lang.model.util.ElementFilter;
...
public List<? extends VariableElement> getGetterMethods(TypeElement targetClass) {
    List<VariableElement> fields =
        ElementFilter.fieldsIn(Collections.singleton(targetClass)).stream()
        .filter(t -> (! t.getModifiers().contains(Modifier.STATIC)))
        .filter(t -> (t.getSimpleName().toString().startsWith("get")
                      || t.getSimpleName().toString().startsWith("is")))
        .collect(Collectors.toList());

    return fields;
}

getFields()(在没有过滤的情况下对您的方法进行类似的更改。)


推荐阅读