Je n'ai jamais utilisé, dans la pratique, mais ce que vous obtenez est que vous pouvez utiliser les classes, en remplacement de vos annotations.
Nous allons créer un exemple artificiel. Dire que nous avons un générateur de documentation. Il lit un @Docu
d'annotation à partir des classes et imprime l' description
d'attribut. Comme ceci:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.List;
public class DokuGenerator {
public static void main(String[] args) throws Exception {
new DokuGenerator(StaticClass.class, StaticClass2.class);
}
public DokuGenerator(Class<?>... classesToDokument) throws Exception {
List<Docu> documentAnnotations = getDocumentAnnotations(classesToDokument);
printDocumentation(documentAnnotations);
}
private List<Docu> getDocumentAnnotations(Class<?>... classesToDokument)
throws Exception {
List<Docu> result = new ArrayList<Docu>();
for (Class<?> c : classesToDokument)
if (c.isAnnotationPresent(Docu.class))
result.add(c.getAnnotation(Docu.class));
return result;
}
private void printDocumentation(List<Docu> toDocument) {
for (Docu m : toDocument)
System.out.println(m.description());
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Docu {
String description();
}
@Docu(description = "This is a static class!")
class StaticClass {
}
@Docu(description = "This is another static class!")
class StaticClass2 {
}
Impressions:
This is a static class!
This is another static class!
Ce que nous voulons accomplir, est, qu'une classe ne peut pas seulement être staticly annoté, mais pouvez ajouter les informations d'exécution de la documentation. Nous sommes très heureux d'utiliser l' @Docu
d'annotation la plupart du temps, mais il existe des cas particuliers que nous voulons spéciale documenation. On peut vouloir ajouter de la performance documenation pour certaines méthodes. Nous pouvons faire cela en laissant une classe implémente l'annotation. Le générateur vérifie d'abord pour l'annotation et, si non présent, il vérifie si la classe implémente l'annotation. Si c'est le cas, il ajoute de la classe à la liste d'annotations.
Comme ceci (seulement deux lignes de code supplémentaires dans le générateur):
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class DokuGenerator {
public static void main(String[] args) throws Exception {
new DokuGenerator(StaticClass.class, StaticClass2.class,
DynamicClass.class);
}
public DokuGenerator(Class<?>... classesToDokument) throws Exception {
List<Docu> documentAnnotations = getDocumentAnnotations(classesToDokument);
printDocumentation(documentAnnotations);
}
private List<Docu> getDocumentAnnotations(Class<?>... classesToDokument)
throws Exception {
List<Docu> result = new ArrayList<Docu>();
for (Class<?> c : classesToDokument)
if (c.isAnnotationPresent(Docu.class))
result.add(c.getAnnotation(Docu.class));
else if (Arrays.asList(c.getInterfaces()).contains(Docu.class))
result.add((Docu) c.newInstance());
return result;
}
private void printDocumentation(List<Docu> toDocument) {
for (Docu m : toDocument)
System.out.println(m.description());
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Docu {
String description();
}
@Docu(description = "This is a static class!")
class StaticClass {
}
@Docu(description = "This is another static class!")
class StaticClass2 {
}
class DynamicClass implements Docu {
public DynamicClass() {
try {
Thread.sleep((long) (Math.random() * 100));
} catch (InterruptedException e) {
// ignore exception to make debugging a little harder
}
}
@Override
public String description() {
long millis = System.currentTimeMillis();
new DynamicClass();
millis = System.currentTimeMillis() - millis;
return "This is a dynamic class. I run on "
+ System.getProperty("os.name")
+ ". The construction of an instance of this class run for "
+ millis + " milliseconds.";
}
@Override
public Class<? extends Annotation> annotationType() {
return Docu.class;
}
}
La sortie est:
This is a static class!
This is another static class!
This is a dynamic class. I run on Windows XP. The construction of an instance of this class run for 47 milliseconds.
Vous havn pas de changer le générateur de code que beaucoup parce que vous pouvez utiliser la classe en tant que remplacement de l'annotation.
Autre exemple, doit être un cadre qui utilise des annotations ou des XML de configuration. Vous pourriez avoir un processeur qui fonctionne sur les annotations. Si vous utilisez XML de configuration, vous pouvez générer des instances de classes qui implémentent les annotations et votre processeur travaille sur eux sans un seul changement! (bien sûr, il existe d'autres moyens pour accomplir le même effet, mais c'est UNE façon de le faire)