我有一个名为 @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/