Java Language
Annotations
Recherche…
Introduction
En Java, une annotation est une forme de métadonnées syntaxiques pouvant être ajoutées au code source Java. Il fournit des données sur un programme qui ne fait pas partie du programme lui-même. Les annotations n'ont aucun effet direct sur le fonctionnement du code qu'elles annotent. Les classes, méthodes, variables, paramètres et packages peuvent être annotés.
Syntaxe
- @AnnotationName // 'Annotation du marqueur' (pas de paramètres)
- @AnnotationName (someValue) // définit le paramètre avec le nom 'value'
- @AnnotationName (param1 = valeur1) // paramètre nommé
- @AnnotationName (param1 = valeur1, param2 = valeur2) // plusieurs paramètres nommés
- @AnnotationName (param1 = {1, 2, 3}) // paramètre de tableau nommé
- @AnnotationName ({value1}) // tableau avec un seul élément comme paramètre avec le nom 'value'
Remarques
Types de paramètres
Seules les expressions constantes des types suivants sont autorisées pour les paramètres, ainsi que les tableaux de ces types:
-
String
-
Class
- types primitifs
- Types enum
- Types d'annotation
Annotations intégrées
L'édition Standard de Java comporte des annotations prédéfinies. Vous n'avez pas besoin de les définir vous-même et vous pouvez les utiliser immédiatement. Ils permettent au compilateur de permettre une vérification fondamentale des méthodes, des classes et du code.
@Passer outre
Cette annotation s'applique à une méthode et dit que cette méthode doit remplacer une méthode de superclasse ou implémenter une définition de méthode de superclasse abstraite. Si cette annotation est utilisée avec un autre type de méthode, le compilateur générera une erreur.
Superclasse en béton
public class Vehicle {
public void drive() {
System.out.println("I am driving");
}
}
class Car extends Vehicle {
// Fine
@Override
public void drive() {
System.out.prinln("Brrrm, brrm");
}
}
Classe abstraite
abstract class Animal {
public abstract void makeNoise();
}
class Dog extends Animal {
// Fine
@Override
public void makeNoise() {
System.out.prinln("Woof");
}
}
Ne marche pas
class Logger1 {
public void log(String logString) {
System.out.prinln(logString);
}
}
class Logger2 {
// This will throw compile-time error. Logger2 is not a subclass of Logger1.
// log method is not overriding anything
@Override
public void log(String logString) {
System.out.println("Log 2" + logString);
}
}
L'objectif principal est de détecter les erreurs de frappe, où vous pensez que vous écrasez une méthode, mais en en définissant une nouvelle.
class Vehicle {
public void drive() {
System.out.println("I am driving");
}
}
class Car extends Vehicle {
// Compiler error. "dirve" is not the correct method name to override.
@Override
public void dirve() {
System.out.prinln("Brrrm, brrm");
}
}
Notez que la signification de @Override
a changé avec le temps:
- Dans Java 5, cela signifiait que la méthode annotée devait remplacer une méthode non abstraite déclarée dans la chaîne de la superclasse.
- A partir de Java 6, il est également satisfait si la méthode annotée implémente une méthode abstraite déclarée dans la hiérarchie des classes / interfaces des classes.
(Cela peut occasionnellement poser problème lors du portage du code vers Java 5.)
@Précis
Cela marque la méthode comme obsolète. Il peut y avoir plusieurs raisons à cela:
l'API est imparfaite et difficile à réparer,
l'utilisation de l'API est susceptible de conduire à des erreurs,
l’API a été remplacée par une autre API,
l'API est obsolète,
l'API est expérimentale et est sujette à des modifications incompatibles,
ou toute combinaison de ce qui précède.
La raison spécifique de l'abandon se trouve généralement dans la documentation de l'API.
L'annotation provoquera une erreur du compilateur si vous l'utilisez. Les IDE peuvent également mettre en évidence cette méthode d'une manière ou d'une autre
class ComplexAlgorithm {
@Deprecated
public void oldSlowUnthreadSafeMethod() {
// stuff here
}
public void quickThreadSafeMethod() {
// client code should use this instead
}
}
@Supprimer les avertissements
Dans presque tous les cas, lorsque le compilateur émet un avertissement, l'action la plus appropriée consiste à corriger la cause. Dans certains cas (code Generics utilisant du code pré-générique non sécurisé, par exemple), cela peut ne pas être possible et il est préférable de supprimer les avertissements que vous attendez et que vous ne pouvez pas corriger. Vous pouvez donc voir plus clairement les avertissements inattendus.
Cette annotation peut être appliquée à une classe, une méthode ou une ligne entière. Il prend la catégorie d'avertissement comme paramètre.
@SuppressWarnings("deprecation")
public class RiddledWithWarnings {
// several methods calling deprecated code here
}
@SuppressWarning("finally")
public boolean checkData() {
// method calling return from within finally block
}
Il est préférable de limiter la portée de l'annotation autant que possible pour éviter la suppression des avertissements inattendus. Par exemple, en limitant la portée de l'annotation à une seule ligne:
ComplexAlgorithm algorithm = new ComplexAlgorithm();
@SuppressWarnings("deprecation") algoritm.slowUnthreadSafeMethod();
// we marked this method deprecated in an example above
@SuppressWarnings("unsafe") List<Integer> list = getUntypeSafeList();
// old library returns, non-generic List containing only integers
Les avertissements pris en charge par cette annotation peuvent varier d'un compilateur à l'autre. Seuls les avertissements unchecked
et deprecation
sont spécifiquement mentionnés dans le JLS. Les types d'avertissement non reconnus seront ignorés.
@SafeVarargs
En raison de l'effacement de type, la void method(T... t)
sera convertie en void method(Object[] t)
ce qui signifie que le compilateur n'est pas toujours en mesure de vérifier que l'utilisation de varargs est de type sécurisé. Par exemple:
private static <T> void generatesVarargsWarning(T... lists) {
Il existe des cas où l'utilisation est sûre, auquel cas vous pouvez annoter la méthode avec l'annotation SafeVarargs
pour supprimer l'avertissement. Cela cache évidemment l'avertissement si votre utilisation est dangereuse aussi.
@Interface fonctionnelle
C'est une annotation facultative utilisée pour marquer une interface fonctionnelle. Cela amènera le compilateur à se plaindre s'il ne se conforme pas à la spécification de FunctionalInterface (possède une seule méthode abstraite)
@FunctionalInterface
public interface ITrade {
public boolean check(Trade t);
}
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
Vérification des annotations d'exécution par réflexion
L'API de réflexion de Java permet au programmeur d'effectuer diverses vérifications et opérations sur les champs de classe, les méthodes et les annotations pendant l'exécution. Toutefois, pour qu'une annotation soit visible au moment de l'exécution, RetentionPolicy
doit être remplacée par RUNTIME
, comme illustré dans l'exemple ci-dessous:
@interface MyDefaultAnnotation {
}
@Retention(RetentionPolicy.RUNTIME)
@interface MyRuntimeVisibleAnnotation {
}
public class AnnotationAtRuntimeTest {
@MyDefaultAnnotation
static class RuntimeCheck1 {
}
@MyRuntimeVisibleAnnotation
static class RuntimeCheck2 {
}
public static void main(String[] args) {
Annotation[] annotationsByType = RuntimeCheck1.class.getAnnotations();
Annotation[] annotationsByType2 = RuntimeCheck2.class.getAnnotations();
System.out.println("default retention: " + Arrays.toString(annotationsByType));
System.out.println("runtime retention: " + Arrays.toString(annotationsByType2));
}
}
Définition des types d'annotation
Les types d'annotation sont définis avec @interface
. Les paramètres sont définis de manière similaire aux méthodes d'une interface régulière.
@interface MyAnnotation {
String param1();
boolean param2();
int[] param3(); // array parameter
}
Les valeurs par défaut
@interface MyAnnotation {
String param1() default "someValue";
boolean param2() default true;
int[] param3() default {};
}
Méta-annotations
Les méta-annotations sont des annotations pouvant être appliquées aux types d'annotation. Une méta-annotation prédéfinie spéciale définit comment les types d'annotation peuvent être utilisés.
@Cible
La méta-annotation @Target
limite les types @Target
l'annotation peut être appliquée.
@Target(ElementType.METHOD)
@interface MyAnnotation {
// this annotation can only be applied to methods
}
Plusieurs valeurs peuvent être ajoutées en utilisant la notation de tableau, par exemple @Target({ElementType.FIELD, ElementType.TYPE})
Valeurs disponibles
ElementType | cible | exemple d'utilisation sur l'élément cible |
---|---|---|
ANNOTATION_TYPE | types d'annotation | |
CONSTRUCTEUR | constructeurs | |
CHAMP | champs, constantes enum | |
VARIABLE LOCALE | déclarations de variables à l'intérieur des méthodes | |
PAQUET | package (dans package-info.java ) | |
MÉTHODE | méthodes | |
PARAMÈTRE | paramètres de méthode / constructeur | |
TYPE | classes, interfaces, énumérations | |
ElementType | cible | exemple d'utilisation sur l'élément cible |
---|---|---|
TYPE_PARAMETER | Type de déclaration de paramètres | |
TYPE_USE | Utilisation d'un type | |
@Rétention
La méta-annotation @Retention
définit la visibilité de l'annotation pendant le processus de compilation ou d'exécution des applications. Par défaut, les annotations sont incluses dans les fichiers .class
, mais ne sont pas visibles lors de l'exécution. Pour rendre une annotation accessible au moment de l'exécution, RetentionPolicy.RUNTIME
doit être défini sur cette annotation.
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
// this annotation can be accessed with reflections at runtime
}
Valeurs disponibles
RetentionPolicy | Effet |
---|---|
CLASSE | L'annotation est disponible dans le fichier .class , mais pas à l'exécution |
DUREE | L'annotation est disponible au moment de l'exécution et est accessible via la réflexion |
LA SOURCE | L'annotation est disponible à la compilation, mais n'est pas ajoutée aux fichiers .class . L'annotation peut être utilisée, par exemple, par un processeur d'annotation. |
@Documenté
La @Documented
méta-annotation est utilisée pour marquer des annotations dont l' utilisation doit être documentée par des générateurs de documentation de l' API comme javadoc . Il n'a pas de valeurs. Avec @Documented
, toutes les classes utilisant l'annotation le listeront sur leur page de documentation générée. Sans @Documented
, il n'est pas possible de voir quelles classes utilisent l'annotation dans la documentation.
@Hérité
La méta-annotation @Inherited
concerne les annotations appliquées aux classes. Il n'a pas de valeurs. Marquer une annotation comme @Inherited
altère le fonctionnement de l'interrogation par annotation.
- Pour une annotation non héritée, la requête examine uniquement la classe en cours d'examen.
- Pour une annotation héritée, la requête vérifie également la chaîne de super-classe (récursivement) jusqu'à ce qu'une instance de l'annotation soit trouvée.
Notez que seules les super-classes sont interrogées: les annotations attachées aux interfaces dans la hiérarchie des classes seront ignorées.
@Repeatable
La méta-annotation @Repeatable
été ajoutée à Java 8. Elle indique que plusieurs instances de l'annotation peuvent être attachées à la cible de l'annotation. Cette méta-annotation n'a aucune valeur.
Obtenir des valeurs d'annotation au moment de l'exécution
Vous pouvez extraire les propriétés actuelles de l'annotation en utilisant Reflection pour récupérer la méthode ou le champ ou la classe à laquelle une annotation est appliquée, puis extraire les propriétés souhaitées.
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
String key() default "foo";
String value() default "bar";
}
class AnnotationExample {
// Put the Annotation on the method, but leave the defaults
@MyAnnotation
public void testDefaults() throws Exception {
// Using reflection, get the public method "testDefaults", which is this method with no args
Method method = AnnotationExample.class.getMethod("testDefaults", null);
// Fetch the Annotation that is of type MyAnnotation from the Method
MyAnnotation annotation = (MyAnnotation)method.getAnnotation(MyAnnotation.class);
// Print out the settings of the Annotation
print(annotation);
}
//Put the Annotation on the method, but override the settings
@MyAnnotation(key="baz", value="buzz")
public void testValues() throws Exception {
// Using reflection, get the public method "testValues", which is this method with no args
Method method = AnnotationExample.class.getMethod("testValues", null);
// Fetch the Annotation that is of type MyAnnotation from the Method
MyAnnotation annotation = (MyAnnotation)method.getAnnotation(MyAnnotation.class);
// Print out the settings of the Annotation
print(annotation);
}
public void print(MyAnnotation annotation) {
// Fetch the MyAnnotation 'key' & 'value' properties, and print them out
System.out.println(annotation.key() + " = " + annotation.value());
}
public static void main(String[] args) {
AnnotationExample example = new AnnotationExample();
try {
example.testDefaults();
example.testValues();
} catch( Exception e ) {
// Shouldn't throw any Exceptions
System.err.println("Exception [" + e.getClass().getName() + "] - " + e.getMessage());
e.printStackTrace(System.err);
}
}
}
La sortie sera
foo = bar
baz = buzz
Annotations répétées
Jusqu'à Java 8, deux instances de la même annotation ne pouvaient pas être appliquées à un seul élément. La solution de contournement standard consistait à utiliser une annotation de conteneur contenant un tableau d'une autre annotation:
// Author.java
@Retention(RetentionPolicy.RUNTIME)
public @interface Author {
String value();
}
// Authors.java
@Retention(RetentionPolicy.RUNTIME)
public @interface Authors {
Author[] value();
}
// Test.java
@Authors({
@Author("Mary"),
@Author("Sam")
})
public class Test {
public static void main(String[] args) {
Author[] authors = Test.class.getAnnotation(Authors.class).value();
for (Author author : authors) {
System.out.println(author.value());
// Output:
// Mary
// Sam
}
}
}
Java 8 fournit un moyen plus propre et plus transparent d'utiliser les annotations de conteneur, en utilisant l'annotation @Repeatable
. Tout d'abord, nous ajoutons ceci à la classe Author
:
@Repeatable(Authors.class)
Ceci indique à Java de traiter plusieurs annotations @Author
comme si elles étaient entourées par le conteneur @Authors
. Nous pouvons également utiliser Class.getAnnotationsByType()
pour accéder au tableau @Author
par sa propre classe, plutôt que par son conteneur:
@Author("Mary")
@Author("Sam")
public class Test {
public static void main(String[] args) {
Author[] authors = Test.class.getAnnotationsByType(Author.class);
for (Author author : authors) {
System.out.println(author.value());
// Output:
// Mary
// Sam
}
}
}
Annotations héritées
Par défaut, les annotations de classe ne s'appliquent pas aux types qui les étendent. Cela peut être modifié en ajoutant l'annotation @Inherited
à la définition d'annotation
Exemple
Considérez les 2 annotations suivantes:
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface InheritedAnnotationType {
}
et
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface UninheritedAnnotationType {
}
Si trois classes sont annotées comme ceci:
@UninheritedAnnotationType
class A {
}
@InheritedAnnotationType
class B extends A {
}
class C extends B {
}
exécuter ce code
System.out.println(new A().getClass().getAnnotation(InheritedAnnotationType.class));
System.out.println(new B().getClass().getAnnotation(InheritedAnnotationType.class));
System.out.println(new C().getClass().getAnnotation(InheritedAnnotationType.class));
System.out.println("_________________________________");
System.out.println(new A().getClass().getAnnotation(UninheritedAnnotationType.class));
System.out.println(new B().getClass().getAnnotation(UninheritedAnnotationType.class));
System.out.println(new C().getClass().getAnnotation(UninheritedAnnotationType.class));
imprimera un résultat similaire à celui-ci (selon les paquets de l'annotation):
null
@InheritedAnnotationType()
@InheritedAnnotationType()
_________________________________
@UninheritedAnnotationType()
null
null
Notez que les annotations ne peuvent être héritées que des classes, pas des interfaces.
Compiler le traitement du temps à l'aide du processeur d'annotations
Cet exemple montre comment effectuer la vérification du temps de compilation d'un élément annoté.
L'annotation
L'annotation @Setter
est un marqueur pouvant être appliqué aux méthodes. L'annotation sera supprimée lors de la compilation et ne sera plus disponible par la suite.
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
public @interface Setter {
}
Le processeur d'annotation
La classe SetterProcessor
est utilisée par le compilateur pour traiter les annotations. Il vérifie si les méthodes annotées avec l'annotation @Setter
sont public
, static
méthodes non static
avec un nom commençant par set
et ayant une lettre majuscule comme 4ème lettre. Si l'une de ces conditions n'est pas remplie, une erreur est écrite dans le Messager
. Le compilateur écrit ceci dans stderr, mais d'autres outils pourraient utiliser ces informations différemment. Par exemple, l'EDI NetBeans permet à l'utilisateur de spécifier des processeurs d'annotation utilisés pour afficher les messages d'erreur dans l'éditeur.
package annotation.processor;
import annotation.Setter;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
@SupportedAnnotationTypes({"annotation.Setter"})
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class SetterProcessor extends AbstractProcessor {
private Messager messager;
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
// get elements annotated with the @Setter annotation
Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(Setter.class);
for (Element element : annotatedElements) {
if (element.getKind() == ElementKind.METHOD) {
// only handle methods as targets
checkMethod((ExecutableElement) element);
}
}
// don't claim annotations to allow other processors to process them
return false;
}
private void checkMethod(ExecutableElement method) {
// check for valid name
String name = method.getSimpleName().toString();
if (!name.startsWith("set")) {
printError(method, "setter name must start with \"set\"");
} else if (name.length() == 3) {
printError(method, "the method name must contain more than just \"set\"");
} else if (Character.isLowerCase(name.charAt(3))) {
if (method.getParameters().size() != 1) {
printError(method, "character following \"set\" must be upper case");
}
}
// check, if setter is public
if (!method.getModifiers().contains(Modifier.PUBLIC)) {
printError(method, "setter must be public");
}
// check, if method is static
if (method.getModifiers().contains(Modifier.STATIC)) {
printError(method, "setter must not be static");
}
}
private void printError(Element element, String message) {
messager.printMessage(Diagnostic.Kind.ERROR, message, element);
}
@Override
public void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);
// get messager for printing errors
messager = processingEnvironment.getMessager();
}
}
Emballage
Pour être appliqué par le compilateur, le processeur d'annotation doit être mis à la disposition du SPI (voir ServiceLoader ).
Pour ce faire, un fichier texte META-INF/services/javax.annotation.processing.Processor
doit être ajouté au fichier jar contenant le processeur d’annotation et l’annotation en plus des autres fichiers. Le fichier doit inclure le nom complet du processeur d’annotation, c’est-à-dire qu’il doit ressembler à ceci:
annotation.processor.SetterProcessor
Nous supposerons que le fichier jar s'appelle AnnotationProcessor.jar
ci-dessous.
Exemple de classe annotée
La classe suivante est un exemple de classe dans le package par défaut, les annotations étant appliquées aux éléments corrects conformément à la stratégie de rétention. Cependant, seul le processeur d'annotation considère uniquement la seconde méthode comme une cible d'annotation valide.
import annotation.Setter;
public class AnnotationProcessorTest {
@Setter
private void setValue(String value) {}
@Setter
public void setString(String value) {}
@Setter
public static void main(String[] args) {}
}
Utilisation du processeur d'annotations avec javac
Si le processeur d'annotations est détecté à l'aide du SPI, il est automatiquement utilisé pour traiter les éléments annotés. Par exemple, compiler la classe AnnotationProcessorTest
utilisant
javac -cp AnnotationProcessor.jar AnnotationProcessorTest.java
donne la sortie suivante
AnnotationProcessorTest.java:6: error: setter must be public
private void setValue(String value) {}
^
AnnotationProcessorTest.java:12: error: setter name must start with "set"
public static void main(String[] args) {}
^
2 errors
au lieu de compiler normalement. Aucun fichier .class
n'est créé.
Cela pourrait être évité en spécifiant l'option -proc:none
pour javac
. Vous pouvez également renoncer à la compilation habituelle en spécifiant -proc:only
place.
Intégration IDE
Netbeans
Les processeurs d'annotation peuvent être utilisés dans l'éditeur NetBeans. Pour ce faire, le processeur d'annotations doit être spécifié dans les paramètres du projet:
allez dans
Project Properties
>Build
>Compiling
ajouter des coches pour
Enable Annotation Processing
etEnable Annotation Processing in Editor
cliquez sur
Add
regard de la liste des processeurs d'annotationsDans la fenêtre qui apparaît, entrez le nom de classe complet du processeur d’annotation et cliquez sur
Ok
.
Résultat
L'idée des annotations
La spécification de langage Java décrit les annotations comme suit:
Une annotation est un marqueur qui associe des informations à une construction de programme, mais n'a aucun effet au moment de l'exécution.
Les annotations peuvent apparaître avant les types ou les déclarations. Il est possible qu'ils apparaissent dans un endroit où ils pourraient s'appliquer à la fois à un type ou à une déclaration.
Ce à quoi s'applique exactement une annotation est régi par la "méta-annotation" @Target
. Voir "Définition des types d'annotation" pour plus d'informations.
Les annotations sont utilisées à des fins multiples. Les cadres tels que Spring et Spring-MVC utilisent des annotations pour définir où les dépendances doivent être injectées ou où les requêtes doivent être acheminées.
D'autres frameworks utilisent des annotations pour la génération de code. Lombok et JPA sont des exemples principaux, qui utilisent des annotations pour générer du code Java (et SQL).
Ce sujet vise à fournir un aperçu complet de:
Comment définir vos propres annotations?
Quelles sont les annotations fournies par le langage Java?
Comment les annotations sont-elles utilisées dans la pratique?
Annotations pour 'this' et paramètres du récepteur
Lorsque les annotations Java ont été introduites pour la première fois, aucune disposition ne permettait d'annoter la cible d'une méthode d'instance ou le paramètre constructeur caché d'un constructeur de classes internes. Cela a été corrigé dans Java 8 avec l'ajout des déclarations de paramètres du récepteur ; voir JLS 8.4.1 .
Le paramètre récepteur est un périphérique syntaxique facultatif pour une méthode d'instance ou un constructeur de classe interne. Pour une méthode d'instance, le paramètre récepteur représente l'objet pour lequel la méthode est appelée. Pour un constructeur de classe interne, le paramètre receiver représente l'instance englobante immédiate de l'objet nouvellement construit. De toute façon, le paramètre récepteur existe uniquement pour permettre au type de l'objet représenté d'être désigné dans le code source, de sorte que le type puisse être annoté. Le paramètre du récepteur n'est pas un paramètre formel; plus précisément, il ne s’agit pas d’une déclaration de variable quelconque (§4.12.3), elle n’est jamais liée à une valeur passée en argument dans une expression d’invocation de méthode ou une expression de création d’instance de classe qualifiée, et elle n’a aucun effet sur temps d'exécution
L'exemple suivant illustre la syntaxe des deux types de paramètres du récepteur:
public class Outer {
public class Inner {
public Inner (Outer this) {
// ...
}
public void doIt(Inner this) {
// ...
}
}
}
Les paramètres du récepteur ont pour seul objectif d’ajouter des annotations. Par exemple, vous pouvez avoir une annotation personnalisée @IsOpen
dont le but est d'affirmer qu'un objet Closeable
n'a pas été fermé lorsqu'une méthode est appelée. Par exemple:
public class MyResource extends Closeable {
public void update(@IsOpen MyResource this, int value) {
// ...
}
public void close() {
// ...
}
}
À un @IsOpen
niveau, l'annotation @IsOpen
sur this
@IsOpen
pourrait simplement servir de documentation. Cependant, nous pourrions potentiellement faire plus. Par exemple:
- Un processeur d’annotations peut insérer un contrôle d’exécution indiquant
this
n’est pas fermé lorsque laupdate
àupdate
est appelée. - Un vérificateur de code peut effectuer une analyse de code statique pour trouver des cas où
this
pourrait être fermé lorsque laupdate
àupdate
est appelée.
Ajouter plusieurs valeurs d'annotation
Un paramètre Annotation peut accepter plusieurs valeurs s'il est défini en tant que tableau. Par exemple, l'annotation standard @SuppressWarnings
est définie comme suit:
public @interface SuppressWarnings {
String[] value();
}
Le paramètre value
est un tableau de chaînes. Vous pouvez définir plusieurs valeurs en utilisant une notation similaire aux initialiseurs de tableau:
@SuppressWarnings({"unused"})
@SuppressWarnings({"unused", "javadoc"})
Si vous ne devez définir qu'une seule valeur, les parenthèses peuvent être omises:
@SuppressWarnings("unused")