2013-07-15 9 views
5

Mi sto solo occupando di javax AnnotationProcessing qui, e mi sono imbattuto in un brutto caso. Illustrerò in una serie di linee pseudo-codice che descrivono il mio processo di apprendimento:Handle TypeMirror and Class gracefully

MyAnnotation ann = elementIfound.getAnnotation(MyAnnotation.class); 
// Class<?> clazz = ann.getCustomClass(); // Can throw MirroredTypeException! 
// Classes within the compilation unit don't exist in this form at compile time! 

// Search web and find this alternative... 

// Inspect all AnnotationMirrors 
for (AnnotationMirror mirror : element.getAnnotationMirrors()) { 
    if (mirror.getAnnotationType().toString().equals(annotationType.getName())) { 
    // Inspect all methods on the Annotation class 
    for (Entry<? extends ExecutableElement,? extends AnnotationValue> entry : mirror.getElementValues().entrySet()) { 
     if (entry.getKey().getSimpleName().toString().equals(paramName)) { 
     return (TypeMirror) entry.getValue(); 
     } 
    } 
    return null; 
    } 
} 
return null; 

Il problema è che ora sto scoprendo che se il codice client contiene una classe di base come java.lang.String o java.lang.Object come un Class parametro, questa linea:

return (TypeMirror) entry.getValue(); 

... si traduce in un ClassCastException, perché l'ambiente AnnotationProcessor è così gentile da recuperare in realtà l'oggetto Class in questo caso.

Ho capito come fare tutto ciò che devo fare con TypeMirror in assenza di Class - devo gestire entrambi nel mio codice ora? C'è un modo per ottenere un TypeMirror da un oggetto Class? Perché non riesco a trovarne uno

risposta

7

La soluzione che ho seguito per questo problema è stato l'utilizzo di ProcessingEnvironment per il cast degli oggetti Class risultanti su TypeMirrors, nel caso in cui avessi classi invece di TypeMirrors. Questo sembra funzionare abbastanza bene.

AnnotationValue annValue = entry.getValue(); 
if (annValue instanceof TypeMirror) { 
    return (TypeMirror) annValue; 
} 
else { 
    String valString = annValue.getValue().toString(); 
    TypeElement elem = processingEnv.getElementUtils().getTypeElement(valString); 
    return elem.asType(); 
} 
+0

In genere, l'API del processore di annotazione consente di evitare l'instanceof utilizzando getKind, getTypeKind, ecc. – Snicolas