Java 6 注解处理——从注解中获取类

标签 java types annotation-processing

我有一个名为 @Pojo 的自定义注释,用于自动生成 wiki 文档:

package com.example.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
public @interface Pojo {
    Class<?> value();
}

我是这样使用的:

@Pojo(com.example.restserver.model.appointment.Appointment.class)

注释资源方法,以便注释处理器可以自动生成描述资源和预期类型的​​ wiki 页面。

我需要在注解处理器中读取 value 字段的值,但出现运行时错误。

在我的处理器的源代码中,我有以下几行:

final Pojo pojo = element.getAnnotation(Pojo.class);
// ...
final Class<?> pojoJavaClass = pojo.value();

但处理器无法使用实际的类。我想我需要一个 javax.lang.model.type.TypeMirror 来代替真正的类(class)。我不知道如何获得。

我得到的错误是:

javax.lang.model.type.MirroredTypeException: Attempt to access Class object for TypeMirror com.example.restserver.model.appointment.Appointment

Appointment 是我的一个 @Pojo 注释中提到的一个类。

不幸的是,关于 Java 注释处理的文档和/或教程似乎很少。尝试谷歌搜索。

最佳答案

我来这里是为了问完全相同的问题。 ...并找到了相同的blog link由拉尔夫发布。

文章很长,但是内容很丰富。故事摘要 - 有两种方法,一种是简单的方法,一种是“更正确”的方法。

这是最简单的方法:

private static TypeMirror getMyValue1(MyAnnotation annotation) {
    try
    {
        annotation.myValue(); // this should throw
    }
    catch( MirroredTypeException mte )
    {
        return mte.getTypeMirror();
    }
    return null; // can this ever happen ??
}

另一种比较繁琐的方式(无一异常(exception)):

private static AnnotationMirror getAnnotationMirror(TypeElement typeElement, Class<?> clazz) {
    String clazzName = clazz.getName();
    for(AnnotationMirror m : typeElement.getAnnotationMirrors()) {
        if(m.getAnnotationType().toString().equals(clazzName)) {
            return m;
        }
    }
    return null;
}

private static AnnotationValue getAnnotationValue(AnnotationMirror annotationMirror, String key) {
    for(Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : annotationMirror.getElementValues().entrySet() ) {
        if(entry.getKey().getSimpleName().toString().equals(key)) {
            return entry.getValue();
        }
    }
    return null;
}


public TypeMirror getMyValue2(TypeElement foo) {
    AnnotationMirror am = getAnnotationMirror(foo, MyAnnotation.class);
    if(am == null) {
        return null;
    }
    AnnotationValue av = getAnnotationValue(am, "myValue");
    if(av == null) {
        return null;
    } else {
        return (TypeMirror)av.getValue();
    }
}

当然,一旦你获得了 TypeMirror,你(至少根据我的经验)几乎总是想要一个 TypeElement:

private TypeElement asTypeElement(TypeMirror typeMirror) {
    Types TypeUtils = this.processingEnv.getTypeUtils();
    return (TypeElement)TypeUtils.asElement(typeMirror);
}

...在我第一次整理出来之前,最后一点不明显的部分花了我一个小时的时间拉头发。这些注释处理器实际上一点也不难编写,API 起初只是 super 困惑而且冗长得令人费解。我很想推出一个帮助类,让所有基本操作都很明显......但这是另一天的故事(如果你想要的话,请给我留言)。

关于Java 6 注解处理——从注解中获取类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7687829/

相关文章:

r - 如何创建一个在 data.frame 中运行良好的新类型?

java - 自定义注释处理器 - Java

java - 从 Tomcat 控制负载均衡器的路由

java - Android Fragment 意外错误

php - PHP 数组可以容纳不同类型的项目吗?

c - 如何在类型定义上将预定义值分配给结构成员?

java - 如何从 ExecutableElement 获取方法体

java - 为 maven-processor-plugin 编写注解处理器

java - 处理中的面向对象编程错误

java - RouteToRecipients Java DSL 无法将多个消息发送到 defaultOutputChannel