【问题标题】:How to determine that class is abstract using Java Mirror API?如何使用 Java Mirror API 确定该类是抽象的?
【发布时间】:2017-10-27 18:23:55
【问题描述】:

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

示例

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

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

如果我打电话给.getModifiers(),我会得到私密。如果我打电话给.getKind(),我会得到“FIELD”。所以,没办法

【问题讨论】:

  • 您的意思是“反射 API”而不是“镜像”吗?
  • 不,我是说Mirror API

标签: java apt annotation-processing mirroring


【解决方案1】:

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

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

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

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

要从类的所有字段中获取信息,您应该使用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;
    }
}

给定以下类:

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]

【讨论】:

  • 抱歉,我没有准确描述这个问题。您的答案非常适合在处理课程时确定类型。但是有什么方法可以确定类内字段类型的这些信息吗?
  • 听起来你想要List&lt;VariableElement&gt; fs = ElementFilter.fieldsIn(someClass.getEnclosedElements());。然后,您可以检查每个 VariableElement 并在它们上调用 getKind() 和/或 getModifiers()
  • 这无济于事。添加了一个示例。
  • @ViktorShatrov 使用所需的中间步骤更新答案以获得Element,您可以致电getKind()getModifiers()
猜你喜欢
  • 2010-11-07
  • 1970-01-01
  • 2010-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多