栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在注释处理器中获取字段类

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在注释处理器中获取字段类

运行注释处理器时,您无权访问已编译的类。注释处理的要点是它发生在预编译中。

相反,您需要创建一个专门处理您的注释类型的注释处理器,然后使用镜像API来访问该字段。例如:

@SupportedAnnotationTypes("com.example.MyAnnotation")public class CompileTimeAnnotationProcessor extends AbstractProcessor {    @Override    public boolean process(Set<? extends TypeElement> annotations,      RoundEnvironment roundEnv) {        // only one annotation, so just use annotations.iterator().next();        Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(     annotations.iterator().next());        Set<VariableElement> fields = ElementFilter.fieldsIn(elements);        for (VariableElement field : fields) { TypeMirror fieldType = field.asType(); String fullTypeClassName = fieldType.toString(); // Validate fullTypeClassName        }        return true;    }}

为了进行验证,您 不能 使用诸如之类的任何尚未编译的类(包括即将通过注释编译的类)

MyType.class
。对于这些,您 只能 使用
字符串 。那是因为注释处理发生在称为“源生成”的预编译阶段,这使您可以在编译器使用注释运行之前生成源代码。

验证字段类型为

java.lang.String
(已编译)的示例验证:

for (VariableElement field : fields) {    TypeMirror fieldType = field.asType();    String fullTypeClassName = fieldType.toString();    if (!String.class.getName().equals(fullTypeClassName)) {        processingEnv.getMessager().printMessage(     Kind.ERROR, "Field type must be java.lang.String", field);    }}

资源资源

  • APT主页
  • Mirror API Javadocs(Java 7和更早版本)
  • 编辑: 镜像API Javadocs(Java 8)
    • 请注意,镜像API现在在Java 8下已标准化,
      javax.lang.model
      并且不赞成使用旧API。有关更多信息,请参见此博客文章。如果您一直在使用这些
      javax
      类,则不必担心。

编辑:

我想获取字段类型以获取对该类型的注释。但这似乎不可行吗?

确实有可能!可以使用以下更多方法来完成此操作

TypeMirror

if (fieldType.getKind() != TypeKind.DECLARED) {    processingEnv.getMessager().printMessage( Kind.ERROR, "Field cannot be a generic type.", field);}DeclaredType declaredFieldType = (DeclaredType) fieldType;TypeElement fieldTypeElement = (TypeElement) declaredFieldType.asElement();

在这里,您有两种选择:

  1. 如果您要查找的注释已经编译(即来自另一个库),则可以直接引用该类以获取注释。
  2. 如果您要查找的注释未编译(即正在
    javac
    运行APT 的当前调用中被编译),则可以通过
    AnnotationMirror
    实例引用它。

已经编译

DifferentAnnotation diffAnn = fieldTypeElement.getAnnotation(        DifferentAnnotation.class);// Process diffAnn

非常简单,这使您可以直接访问注释本身。

未编译

请注意,无论注释是否被编译,该解决方案都将起作用,它不如上面的代码那么干净。

这是我曾经编写的几个方法,用于通过其类名称从注释镜像中提取特定值:

private static <T> T findAnnotationValue(Element element, String annotationClass,        String valueName, Class<T> expectedType) {    T ret = null;    for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) {        DeclaredType annotationType = annotationMirror.getAnnotationType();        TypeElement annotationElement = (TypeElement) annotationType     .asElement();        if (annotationElement.getQualifiedName().contentEquals(     annotationClass)) { ret = extractValue(annotationMirror, valueName, expectedType); break;        }    }    return ret;}private static <T> T extractValue(AnnotationMirror annotationMirror,        String valueName, Class<T> expectedType) {    Map<ExecutableElement, AnnotationValue> elementValues = new HashMap<ExecutableElement, AnnotationValue>( annotationMirror.getElementValues());    for (Entry<ExecutableElement, AnnotationValue> entry : elementValues .entrySet()) {        if (entry.getKey().getSimpleName().contentEquals(valueName)) { Object value = entry.getValue().getValue(); return expectedType.cast(value);        }    }    return null;}

假设您正在寻找

DifferentAnnotation
注释,并且您的源代码如下所示:

@DifferentAnnotation(name = "My Class")public class MyClass {    @MyAnnotation    private String field;    // ...}

此代码将打印

My Class

String diffAnnotationName = findAnnotationValue(fieldTypeElement,        "com.example.DifferentAnnotation", "name", String.class);System.out.println(diffAnnotationName);


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/516500.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号