如何使用Java镜像API判断class是抽象的?

How to determine that class is abstract using Java Mirror API?

我在写注解处理器,想根据javax.lang.model.element.VariableElement判断对应的字段类型是抽象的还是具体的class。或者它是一个接口。 怎么做?

例子

@SomeAnnotation
public class SomeClass {
    private Map<String,String> interfaceField;
    private AbstractMap<String,String> abstractField;
    private HashMap<String, String> concreteField;
}

所以,每个字段我都有 VariableElement。并且想知道 interfaceField 的类型是一个接口,abstractField 的类型是抽象的,而 concreteField[=30 的类型=]是具体的class。

如果我调用 .getModifiers(),我得到 private。如果我调用 .getKind(),我得到 "FIELD"。所以,没办法

Element#getModifiers() 会告诉您 class 是否为 abstract

    if (element.getModifiers().contains(Modifier.ABSTRACT)) { ... }

Element#getKind() 会告诉你它是否是 interface:

    if (element.getKind() == ElementKind.INTERFACE) { ... }

要从 class 的所有字段中获取信息,您应该使用 TypeVisitor:

TypeVisitor<Void, VariableElement> type_visitor = new TV();
for (VariableElement field : ElementFilter.fieldsIn(cls.getEnclosedElements())) {
    field.asType().accept(type_visitor, field);
}

其中type_visitor是你自己定制的TypeVisitor,通过各种套路,可以得到一个Element你可以调用上面的getKind()getModifiers() 方法:

class TV extends SimpleTypeVisitor8<Void, VariableElement> {

    @Override
    public Void visitDeclared(DeclaredType type, VariableElement field) {
        System.out.println(field.getSimpleName());
        System.out.println("  type = " + type.toString());
        System.out.println("  modifiers = " + field.getModifiers());
        Element e = type.asElement();
        System.out.println("    kind = " + e.getKind());
        System.out.println("    modifiers = " + e.getModifiers());
        return null;
    }
}

给出以下 class:

public class MyClass {
    private Properties properties;
    private List<String> strings;
    // ...
}

我得到以下输出:

properties
  type = java.util.Properties
  modifiers = [private]
    kind = CLASS
    modifiers = [public]
strings
  type = java.util.List<java.lang.String>
  modifiers = [private]
    kind = INTERFACE
    modifiers = [public, abstract]