Java 6注释处理 – 从注释中获取类
我有一个名为@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)
来标注一个资源方法,这样注释处理器可以自动生成一个描述它所期望的资源和types的wiki页面。
我需要读取注释处理器中的value
字段的value
,但是我得到一个运行时错误。
在我的处理器的源代码中,我有以下几行:
final Pojo pojo = element.getAnnotation(Pojo.class); // ... final Class<?> pojoJavaClass = pojo.value();
但实际的类没有提供给处理器。 我想我需要一个javax.lang.model.type.TypeMirror
来代替真实的类。 我不知道如何得到一个。
我得到的错误是:
javax.lang.model.type.MirroredTypeException: Attempt to access Class object for TypeMirror com.example.restserver.model.appointment.Appointment
Appointment
是在我的@Pojo
注释中提到的一个类。
不幸的是,关于Java注释处理的文档和/或教程似乎很less。 试图用Googlesearch。
你读过这篇文章: http : //blog.retep.org/2009/02/13/getting-class-values-from-annotations-in-an-annotationprocessor/ ?
诀窍是实际使用getAnnotation()并捕获MirroredTypeException。 令人惊讶的是,exception提供了所需类的TypeMirror。
我不知道这是否是一个好的解决scheme,但它是一个。 在我个人看来,我会尝试获得types的Mirroredtypes,但我不知道这是否可能。
我来到这里问精确的同样的问题。 …并find了Ralph发布的相同的博客链接 。
这是一篇很长的文章,但非常丰富。 故事总结 – 有两种方法可以做到这一点,简单的方法和“更正确”的方式。
这是简单的方法:
private static TypeMirror getMyValue1(MyAnnotation annotation) { try { annotation.myValue(); // this should throw } catch( MirroredTypeException mte ) { return mte.getTypeMirror(); } return null; // can this ever happen ?? }
另一种更乏味的方式(没有例外):
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,你(至less在我的经验)几乎总是想要一个TypeElement:
private TypeElement asTypeElement(TypeMirror typeMirror) { Types TypeUtils = this.processingEnv.getTypeUtils(); return (TypeElement)TypeUtils.asElement(typeMirror); }
…最后一点不明显的东西在我第一次把它整理出来之前花了我一个小时的头发。 这些注释处理器实际上并不难写,API起初只是超级混淆,而且大脑细致。 我很想放出一个帮助课,让所有的基本操作变得明显…但这是另一个故事(如果你想要的话,我可以)。