devstory

Le Tutoriel de Java Annotation

  1. Qu'est-ce que Annotation?
  2. Des annotations intégrées
  3. Écrire Votre Annotation
  4. Outil de Traitement des Annotations (Connaissances Avancées)

1. Qu'est-ce que Annotation?

Annotation de Java sont utilisées pour fournir des métadonnées pour votre code Java. Étant des méta-données, les Annotation n'influent pas directement sur l'exécution de votre code, bien que certains types d'annotations puissent effectivement être utilisés à cette fin. Les Annotation de Java ont été ajoutées à Java à partir de Java 5.
Annotation de Java sont typiquement utilisées aux buts suivants:
  1. Instructions du compilateur (Compiler)
  2. Instructions de construction (Build-time)
  3. Instructions d'exécution (Runtime)
Instructions pour le compilateur
Java possède 3 Annotation intégrées que vous pouvez utiliser pour donner des instructions au compilateur Java.
  • @Deprecated
  • @Override
  • @SuppressWarnings
Ces annotations sont expliquées plus en détail plus loin dans ce document.
Instruction en temps de construction (Build-time)
Les annotations Java peuvent être utilisées au moment de la construction (Build-time), lorsque vous créez votre projet logiciel. Le processus de construction comprend la génération du code source, la compilation de la source, la génération de fichiers XML (par exemple, des descripteurs de déploiement), le packaging du code compilé et des fichiers dans un fichier JAR, etc. La construction du logiciel est généralement effectuée par un outil de construction automatique comme Apache Ant ou Apache Maven . Les outils de construction peuvent scanner votre code Java pour des annotations spécifiques et générer du code source ou d'autres fichiers basés sur ces annotations.
Instructions d'exécution (Runtime)
Normalement, les annotations de Java ne sont pas présentes dans votre code Java après la compilation. Il est toutefois possible de définir vos propres annotations disponibles au moment de l'exécution. Ces annotations peuvent ensuite être consultées via Java Reflection et utilisées pour donner des instructions à votre programme ou à une API tierce.

2. Des annotations intégrées

Il existe 3 annotations importantes de Java
  • @Deprecated
  • @Override
  • @SuppressWarnings
@Deprecated
Il s'agit d'une annotation utilisée pour annoter quelque chose obsolète comme classe ou méthode; Et pour le mieux, nous ne devrions plus l'utiliser. Si vous utilisez quelque chose obsolète, le compilateur vous informera que vous devriez utiliser une autre manière. Ou avec la programmation IDE comme Eclipse, cela vous montre également des notifications visuelles.
DeprecatedMethodDemo.java
package org.o7planning.tutorial.ann.builtin;

import java.util.Date;

public class DeprecatedMethodDemo {

  /**
   * @deprecated replaced by {@link #todo(String,Date)}
   */
  @Deprecated
  public void todoJob(String jobName) {
      System.out.println("Todo " + jobName);
  }

  public void todo(String jobName, Date atTime) {
      System.out.println("Todo " + jobName + " at " + atTime);
  }

  public void todoNothing() {
      System.out.println("Todo Nothing");
  }

  public static void main(String[] args) {

      DeprecatedMethodDemo obj = new DeprecatedMethodDemo();

      obj.todoJob("Java coding");

      obj.todoNothing();
  }
}
Voici sont des photos, Eclipse vous informe:
@Override
L'annotation @Override est utilisée ci-dessus des méthodes qui remplacent les méthodes dans une superclasse (superclass). Si la méthode ne correspond pas à une méthode dans la superclasse, le compilateur vous donnera une erreur.

L'annotation @Override n'est pas nécessaire pour remplacer une méthode dans une superclasse. C'est pourtant une bonne idée de l'utiliser encore. Dans le cas où quelqu'un a changé le nom de la méthode surchargée dans la superclasse, votre méthode de sous-classe ne la remplacerait plus. Sans l'annotation @Override, vous ne le verrez pas. Avec l'annotation @Override, le compilateur vous dirait que la méthode dans la sous-classe ne remplace aucune méthode dans la superclasse.
Observez un exemple:
Job.java
package org.o7planning.tutorial.ann.builtin;

public class Job {

	// C'est une méthode de la classe Job.
	public String getName() {
		return null;
	}

}
JavaCoding.java
package org.o7planning.tutorial.ann.builtin;

public class JavaCoding extends Job {

	// Cette méthode est remplacée par getName () de la superclasse.
	// @Override n'est pas obligé d'annoter sur cette méthode.
	// Mais il est nécessaire que quelqu'un change le nom de la méthode getName()  en classe de superclasse, un message d'erreur vous le dira.
	@Override
	public String getName() {
		return "Java Coding";
	}

}
Et voici l'alerte du compilateur Java Compiler:
@SuppressWarnings
L'annotation @SuppressWarnings fait que le compilateur supprime les avertissements pour une méthode donnée. Par exemple, si une méthode appelle une méthode obsolète, ou crée un type non sécurisé, le compilateur peut générer un avertissement. Vous pouvez supprimer ces avertissements en annotant la méthode contenant le code avec l'annotation @SuppressWarnings.
Voir un exemple:
SuppressWarningsDemo.java
package org.o7planning.tutorial.ann.builtin;

import java.util.Date;

public class SuppressWarningsDemo {

  @SuppressWarnings("deprecation")
  public Date getSomeDate() {

      Date date = new Date(2014, 9, 25);
      return date;
  }

}
Voir l'avertissement du compilateur:
SuppressWarningsDemo2.java
package org.o7planning.tutorial.ann.builtin;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class SuppressWarningsDemo2 {

	public List<?> getDatas() {
		List<String> list = new ArrayList<String>();
		list.add("One");
		return list;
	}

	@SuppressWarnings({ "deprecation", "unused", "unchecked" })
	public void processDatas() {

		// Vous utilisez Constructeur obsolète.
		// La variable «date» a été créée, mais pas utilisée
		Date date = new Date(2014, 9, 25);

		// Utiliser le type (cast) n'est peu sur.
		// La variable 'datas' est créée, mais n'est pas utilisées dans le code.
		List<String> datas = (List<String>) this.getDatas();
	}

}
Voir l'avertissement du compilateur:

3. Écrire Votre Annotation

L'utilisation de @interface est un mot-clé de déclaration d'une Annotation, et cette annotation est assez similaire à une interface. Une annotation peut avoir ou non des éléments (element).
Les caractéristiques des éléments (element) d'une annotation:
  • Il n'y a pas de corps de fonction
  • Il n'y a pas de paramètre fonctionnel
  • La déclaration de retour doit être un type spécifique:
    • Type primitif (boolean, int, float, ...)
    • Enum
    • Annotation
    • Classe (Par exemple String.class)
  • L'élément peut avoir des valeurs par défaut
Votre première Annotation
MyFirstAnnotation.java
package org.o7planning.tutorial.ann1;

public @interface MyFirstAnnotation {

	// L'élément 'name'.
	public String name();

	// L'élément 'description', sa valeur par défaut est "".
	public String description() default "";

}
L'annotation peut être utilisée sur:
  • TYPE - Classe, interface (y compris le type d'annotation) ou déclaration d'énumération.
  • FIELD - Champ de déclaration (field), inclut des constantes d'énumération.
  • METHOD - Déclaration de méthode.
  • PARAMETER - Déclaration de paramètre
  • CONSTRUCTOR - Déclaration de constructeur
  • LOCAL_VARIABLE - Déclaration de variable locale.
  • ANNOTATION_TYPE - Déclaration d'Annotation
  • PACKAGE - Déclaration de package.
UsingMyFirstAnnotation.java
package org.o7planning.tutorial.ann1;

@MyFirstAnnotation(name = "Some name", description = "Some description")
public class UsingMyFirstAnnotation {

	// L'annotation est annotée sur un Constructeur.
	// La valeur de l'élément 'name' est "John"
	// La valeur de l'élément 'description' est "Write by John".
	@MyFirstAnnotation(name = "John", description = "Write by John")
	public UsingMyFirstAnnotation() {

	}

	// L'annotation est annotée sur une méthode.
	// La valeur de l'élément 'name' est "Tom"
	// L'élément 'description' n'est pas déclaré, on lui attribuera une valeur par défaut.
	@MyFirstAnnotation(name = "Tom")
	public void someMethod() {

	}

	// Une annotation est annotée sur le paramètre de méthode.
	public void todo(@MyFirstAnnotation(name = "none") String job) {

		// Une annotation est annotée sur une variable locale.
		@MyFirstAnnotation(name = "Some name")
		int localVariable = 0;

	}

}
Annotation avec l'élément value. (Spécial)
Une Annotation a l'élément nommé value ayant quelques caractéristiques spéciales:
AnnWithValue.java
package org.o7planning.tutorial.ann2;

public @interface AnnWithValue {

	// Un élément est nommé 'value', de l'annotation.
	// Il n'y a un peu particulier lors de l'utilisation cet élément.
	public int value();

	// L'élément 'name'
	public String name() default "";

}
UsingAnnWithValue.java
package org.o7planning.tutorial.ann2;

public class UsingAnnWithValue {

	// Initialisez les éléments des Annotations de la façon habituelle.
	@AnnWithValue(name = "Name1", value = 100)
	public void someMethod1() {

	}

	// Initialisez les éléments de l'annotation de la façon habituelle.
	// L'élément 'name' de cette Annotation a une valeur par défaut.
	@AnnWithValue(value = 100)
	public void someMethod2() {

	}

	// L'élément nommé 'value' est spéciale.
	// Au lieu d'écrire @AnnWithValue(value = 100)
	// Vous devez seulement écrire @AnnWithValue(100)
	@AnnWithValue(100)
	public void someMethod3() {

	}
}
@Retention & @Target
@Retention & @Target sont 2 annotations disponibles de Java.
@Retention
@Retention: est utilisé pour noter le niveaux d'existence de certaines annotation.
En particulier, il existe 3 niveaux de de conscience de l'existence de la chose notée:
  1. RetentionPolicy.SOURCE: Existe sur le code source et sans reconnaissance du compilateur.
  2. RetentionPolicy.CLASS: Son existence est identifiée par le compilateur, mais pas par la machine virtuelle au moment d'exécution (Runtime).
  3. RetentionPolicyRUNTIME: Atteint le plus haut niveau d'existence, est identifié par le compilateur (compiler) et par la machine virtuelle au moment d'exécution.
@Target
@Target: Est utilisé pour noter une autre annotation et sa portée d'utilisation.
  1. ElementType.TYPE - Joint sur la déclaration de Classe, interface, énumération, annotation.
  2. ElementType.FIELD - Joint sur la déclaration de champ (field), y compris la constante enum.
  3. ElementType.METHOD - Joint sur la déclaration de méthode.
  4. ElementType.PARAMETER - Joint sur la déclaration de paramètre
  5. ElementType.CONSTRUCTOR - Joint sur la déclaration de constructeur
  6. ElementType.LOCAL_VARIABLE - Joint sur la déclaration de variable locale
  7. ElementType.ANNOTATION_TYPE - Joint sur la déclaration d' Annotation
  8. ElementType.PACKAGE - Joint sur la déclaration de package.
AnnFM.java
package org.o7planning.tutorial.ann3;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// Cette annotation indique que AnnFM n'est reconnu que sur le code source.
// Ce ne sera pas reconnu par le compilateur (compiler),
// Et dans le temps de fonctionnement, la machine virtuelle ne connaît pas non plus son existence.
@Retention(value = RetentionPolicy.SOURCE)

// Cette annotation indique que:
// AnnFM ne sera annoté (annotate) que sur FIELD ou METHOD.
@Target(value = { ElementType.FIELD, ElementType.METHOD })
public @interface AnnFM {

}
UsingAnnFM.java
package org.o7planning.tutorial.ann3;

public class UsingAnnFM {

	// AnnFM est autorisé à annoter sur FIELD ou METHOD.
	@AnnFM
	protected int someField = 100;

	// AnnFM est autorisé à annoter  (annotate) sur FIELD ou METHOD.
	@AnnFM
	public void someMethod() {

	}

}
Annotation & Reflection

Remarque: Si vous venez de commencer à apprendre Java, vous pouvez ignorer cette section. Parce qu'il nécessite des connaissances synthétisées et l'apprentissage, il est inutile au niveau initial.

Java Reflection peut identifier des choses comme Classe, champ, méthode annotée par quelques Annotation. Et bien sûr, il ne peut reconnaître que l'annotation avec @Retention(RetentionPolicy.RUNTIME)
L'exemple ci- desous décrit un programme de lecture d'annotations sur les fichiers Java d'origine et la création de fichiers Html. Chaque classe équivaut à un fichier html.
AnnHtmlUL.java
package org.o7planning.tutorial.ann4;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)

// Cette Annotation dit que:
// AnnHtmlUL est uniquement utilisé pour Class, interface, annotation, énumération.
@Target(value = { ElementType.TYPE })

// AnnHtmlUL: Simulation de l'étiquette (tag) <UL> en HTML.
public @interface AnnHtmlUL {

	public String border() default "border:1px solid blue;";
	
}
AnnHtmlLI.java
package org.o7planning.tutorial.ann4;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(value = { ElementType.FIELD, ElementType.METHOD })

// Simulation de l'étiquette (tag) <LI> en HTML.
public @interface AnnHtmlLI {

	public String background();

	public String color() default "red";
	
}
DocumentClass.java
package org.o7planning.tutorial.ann4;

@AnnHtmlUL(border = "1px solid red")
public class DocumentClass {

	private String author;

	@AnnHtmlLI(background = "blue", color = "black")
	public String getDocumentName() {
		return "Java Core";
	}

	@AnnHtmlLI(background = "yellow")
	public String getDocumentVersion() {
		return "1.0";
	}

	@AnnHtmlLI(background = "green")
	public void setAuthor(String author) {
		this.author = author;
	}

	@AnnHtmlLI(background = "red", color = "black")
	public String getAuthor() {
		return author;
	}
	
	// Cette méthode n'est pas annotée par n'importe quelle annotation.
	public float getPrice()  {
		return 100;
	}

}
HtmlGenerator.java
package org.o7planning.tutorial.ann4;

import java.lang.reflect.Method;

public class HtmlGenerator {

	public static void main(String[] args) {

		Class<?> clazz = DocumentClass.class;

		// Vérifiez si cette classe est annotée  (annotate) par AnnHtmlUL ou non.
		boolean isHtmlUL = clazz.isAnnotationPresent(AnnHtmlUL.class);

		StringBuilder sb = new StringBuilder();
		if (isHtmlUL) {

			// Sortez l'objet AnnHtmlUL, annoté sur cette classe.
			AnnHtmlUL annUL = clazz.getAnnotation(AnnHtmlUL.class);

			sb.append("<H3>" + clazz.getName() + "</H3>");
			sb.append("\n");

			// Obtenez la valeur de l'élément 'border' de AnnHtmlUL.
			String border = annUL.border();

			sb.append("<UL style='border:" + border + "'>");

			// Ajoutez une nouvelle ligne.
			sb.append("\n");

			Method[] methods = clazz.getMethods();

			for (Method method : methods) {
				// Vérifiez si cette méthode est annoté (annotate)
				// par AnnHtmlLI ou pas?
				if (method.isAnnotationPresent(AnnHtmlLI.class)) {
					// Obtenez l'annotation.
					AnnHtmlLI annLI = method.getAnnotation(AnnHtmlLI.class);

					// Obtenez les valeurs de l'élément de l'AnnHtmlLI.
					String background = annLI.background();
					String color = annLI.color();

					sb.append("<LI style='margin:5px;padding:5px;background:" + background + ";color:" + color + "'>");
					sb.append("\n");
					sb.append(method.getName());
					sb.append("\n");
					sb.append("</LI>");
					sb.append("\n");
				}
			}
			sb.append("</UL>");
		}
		writeToFile(clazz.getSimpleName() + ".html", sb);
	}

	// Écrivez  des informations sur l'écran de Console (ou fichier).
	private static void writeToFile(String fileName, StringBuilder sb) {
		System.out.println(sb);
	}

}
Résultats de l'exécution de l'exemple:
<H3>org.o7planning.tutorial.ann4.DocumentClass</H3>
<UL style='border:1px solid red'>
<LI style='margin:5px;padding:5px;background:blue;color:black'>
getDocumentName
</LI>
<LI style='margin:5px;padding:5px;background:yellow;color:red'>
getDocumentVersion
</LI>
<LI style='margin:5px;padding:5px;background:green;color:red'>
setAuthor
</LI>
<LI style='margin:5px;padding:5px;background:red;color:black'>
getAuthor
</LI>
</UL>
Le cas d'écrire un fichier html:

4. Outil de Traitement des Annotations (Connaissances Avancées)

The situation is that:
Une situation se pose:

Vous créez vos propres Annotation et les utiliser dans votre application Java. Vous définissez les règles pour ces annotations. Vous souhaitez que le compilateur Java notifie l'erreur lors qu'il ne respecte pas les règles, le cas échéant, au moment de la compilation. Si vous utilisez Eclipse pour écrire des codes, vous souhaitez que Eclipse notifie l'erreur d'utilisation sur IDE.

C'est totalement possible avec APT (Annotation Processing Tool).
Vous pouvez voir le guide d'APT à:

Java Basic

Show More