Je sais que si nous connaissons la classe d'annotation, nous pouvons facilement obtenir l'annotation spécifique et accéder à son attribut. Par exemple:
field.getAnnotation(Class<T> annotationClass)
Qui renverra une référence d'interface d'annotation spécifique, afin que vous puissiez facilement accéder à ses valeurs.
Ma question est de savoir si je n'ai aucune connaissance préalable de la classe d'annotations particulière. Je veux juste utiliser la réflexion pour obtenir tous les noms de classe d'annotation et leurs attributs au moment de l'exécution dans le but de vider les informations de classe par exemple sous forme de fichier json. Comment puis-je le faire facilement.
Annotation[] field.getAnnotations();
Cette méthode ne renverra que des proxys dynamiques des interfaces d'annotation.
Contrairement à ce que l'on pourrait attendre, les éléments d'une annotation ne sont pas des attributs - ce sont en fait des méthodes qui renvoient la valeur fournie ou une valeur par défaut.
Vous devez parcourir les méthodes des annotations et les invoquer pour obtenir les valeurs. Utilisez annotationType()
pour obtenir la classe de l'annotation, l'objet renvoyé par getClass()
n'est qu'un proxy.
Voici un exemple qui imprime tous les éléments et leurs valeurs de @Resource
annotation d'une classe:
@Resource(name = "foo", description = "bar")
public class Test {
public static void main(String[] args) throws Exception {
for (Annotation annotation : Test.class.getAnnotations()) {
Class<? extends Annotation> type = annotation.annotationType();
System.out.println("Values of " + type.getName());
for (Method method : type.getDeclaredMethods()) {
Object value = method.invoke(annotation, (Object[])null);
System.out.println(" " + method.getName() + ": " + value);
}
}
}
}
Sortie:
Values of javax.annotation.Resource
name: foo
type: class Java.lang.Object
lookup:
description: bar
authenticationType: CONTAINER
mappedName:
shareable: true
Merci à Aaron pour avoir souligné la nécessité de lancer l'argument null
pour éviter les avertissements.
Juste pour donner suite à la réponse ci-dessus (je n'ai pas assez de représentants pour y répondre):
method.invoke(annotation, null)
doit être modifié comme suit, sinon il lève une exception:
method.invoke(annotation, (Object[])null) or method.invoke(annotation, new Object[0])