Soirée Paris JUG – Les annotations Java

Le 14 décembre 2010 s’est tenu la  soirée du ParisJUG à l’ISEP portant sur les annotations Java. J’ai eu la chance d’y assister dans le cadre du sponsoring de FastConnect.

La soirée à été animé par Olivier Croisier, auteur du blog The Coder’s Breakfast.

La soirée s’est découpé en deux parties :

  • Le concept d’annotations.
  • Les possibilités offertes par les annotations.

Les annotations Java sont des méta-informations qui peuvent être utilisés dans les différentes phases du cycle de vie d’une applications, à savoir :

  • à la génération du code.
  • à l’exécution de l’application.

Les annotations Javadoc sont les ancêtres des annotations qui sont apparus avec Java 1.5.

/**
* Documentation sur une méthode.
* @param args Le permier argument de la méthode.
* @return Ce que retourne la méthode.
*/

Ce bout de code présent juste au dessus d’une méthode permet à l’outil Javadoc de générer la documentation de l’application.

Mais où trouve-t on des annotations ?

Tout ou presque est annotable en Java, du package à l’argument d’une méthode en passant par les classes. Olivier Croisier nous donne l’exemple suivant de l’utilisation de l’annotation @Deprecated fournit par Java 5 :


@Deprecated
public class Pojo {

@Deprecated
private int foo;

@Deprecated
public Pojo() {
@Deprecated
int localVar = 0;
}

@Deprecated
public int getFoo() {
return foo;
}
public void setFoo(@Deprecated int foo) {
this.foo = foo;
}
}

Les annotations sur les packages peuvent être renseigner dans un fichier package-info.java :


/**
 * La documentation sur ce package.
 */
@UneAnnotation
package org.fastconnect.unpackage;

La création d’une annotation.

Une annotation est une interface qui réponds à certaines spécificités, comme nous pouvons le voir dans l’exemple suivant :

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.TYPE})
public @interface Toaster {

 public static enum Level { LOW , MIDDLE , HARD }

 String toasterName() default "";

 Level level() default Level.MIDDLE;

}

Notre annotation « @Toaster » est définit donc une @interface. Elle est elle-même annotée par @Retention et @Target.

  • @Retention permet de définir la durée de vie de notre annotation dans le cycle de vie du code. Ici, nous décidons de la garder jusque dans le Runtime.
  • @Target permet de définir les cibles qui pourront porter notre annotations. Nous décidons ici de permettre aux attributs et aux classes d’être annotées par @Toaster.

Comme une interface, notre annotation peut comporter des attributs, comme nous pouvons le voir avec notre énumération Level.

La différence avec les interfaces réside dans les signature des méthodes. En effet, le mot clé default permet de définir une compile-time constant qui sera utilisé par défaut.

Les annotations, a quoi ca peut servir cette bête la ?

Il est possible d’utiliser les annotations à différents moment du cycle de vie de l’application. A l’image des métas données pour Javadoc, il est possible de se faire des annotations pour la réalisation de documentation. L’exemple d’une annotation @Todo est souvent utilisé dans ce sens.

Si les annotations sont conservées au Runtime, les mécanismes de réflexion Java permettent de récupérer les annotations ainsi que leur contenu. Il peut donc être possible de faire de la méta programmation à l’aide des annotations. Les annotations JPA ou des EJB 3 sont des bons exemples de méta programmation.

APT pour Annotation Processing Tool est un outil qui permet de processer les annotations lors de la compilation. Il est ainsi possible se servir des annotations pour étendre des règles de compilation ou de développer un générateur de code.

Conclusion

Comme nous avons pu le voire, les annotations offre de nombreuses possibilités, que ce soit lors de l’écriture du code. Cependant, il ne faut pas oublier que trop d’annotations tue les annotations.