如何使用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]
我在写注解处理器,想根据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]