suppresswarnings sirven sirve que para notacion las ejemplo crear categorias anotaciones annotation java types annotation-processing

sirven - Procesamiento de anotación Java 6: obtener una clase de una anotación



para que sirven las anotaciones (2)

Tengo una anotación personalizada llamada @Pojo que uso para la generación automática de documentación 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(); }

Lo uso así:

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

anotar un método de recursos para que el procesador de anotaciones pueda generar automáticamente una página wiki que describa el recurso y el tipo que espera.

Necesito leer el valor del campo de value en un procesador de anotación, pero obtengo un error de tiempo de ejecución.

En el código fuente de mi procesador, tengo las siguientes líneas:

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

pero la clase real no está disponible para el procesador. Creo que necesito un javax.lang.model.type.TypeMirror lugar de un sustituto para la clase real. No estoy seguro de cómo conseguir uno.

El error que estoy recibiendo es:

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

La Appointment es una clase mencionada en una de mis anotaciones @Pojo .

Desafortunadamente, el documento y / o tutoriales sobre el procesamiento de la anotación Java parece escaso. Intenté googlear.



Vine aquí para hacer la misma pregunta EXACTA. ... y encontró el mismo http://blog.retep.org/2009/02/13/getting-class-values-from-annotations-in-an-annotationprocessor/ publicado por Ralph.

Es un artículo largo, pero muy rico. Resumen de la historia: hay dos formas de hacerlo, la manera fácil y la manera "más correcta".

Esta es la manera fácil:

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

La otra forma más tediosa (sin excepciones):

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(); } }

Por supuesto, una vez que obtiene un TypeMirror, usted (al menos en mi experiencia) casi siempre quiere un TypeElement en su lugar:

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

... ese último pequeño truco no obvio me tomó una hora de tirar del pelo antes de que lo resolviera la primera vez. Estos procesadores de anotaciones en realidad no son tan difíciles de escribir, las API son muy confusas al principio y extremadamente detalladas. Estoy tentado de crear una clase de ayuda que haga que todas las operaciones básicas sean obvias ... pero esa es una historia para otro día (cómprame si quieres).