English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Dans ce tutoriel, nous allons apprendre différents types d'annotations Java à l'aide d'exemples.
Java annotations sont les métadonnées de notre code source (les données sur les données). Java SE fournit plusieurs annotations prédéfinies. De plus, nous pouvons créer des annotations personnalisées selon nos besoins.
Si vous ne savez pas ce que sont les annotations, veuillez visiterJava annotationsTutoriel.
Ces annotations peuvent être classées en:
1. Annotations prédéfinies
@Deprecated
@Override
@SuppressWarnings
@SafeVarargs
@FunctionalInterface
2. Annotations personnalisées
3. Annotations de métadonnées
@Retention
@Documented
@Target
@Inherited
@Repeatable
L'annotation @Deprecated est une annotation de marqueur indiquant que l'élément (classe, méthode, champ, etc.) est obsolète et a été remplacé par un élément mis à jour.
sa syntaxe est :
@Deprecated accessModifier returnType deprecatedMethodName() { ... }
Lorsque le programme utilise des éléments déclarés comme dépréciés, le compilateur génère un avertissement.
Nous utilisons la marqueur @deprecated de Javadoc pour enregistrer les éléments dépréciés.
/** * @déprécié * Pourquoi il est déprécié */ @Deprecated accessModifier returnType deprecatedMethodName() { ... }
class Main { /** * @déprécié * Cette méthode est obsolète et a été remplacée par newMethod() }} */ @Deprecated public static void deprecatedMethod() { System.out.println("Deprecated method"); } public static void main(String args[]) { deprecatedMethod(); } }
Résultat de la sortie
Deprecated method
L'annotation @Override spécifie que la méthode de la sous-classe utilise le même nom de méthode, le type de retour et la liste des paramètres pour surcharger la méthode de la classe parent.
@Override n'est pas obligatoire lors de la redéfinition d'une méthode. Cependant, si elle est utilisée, le compilateur donnera une erreur si une erreur se produit lors de la surcharge de la méthode (par exemple, un type de paramètre incorrect).
class Animal { //Méthode de redéfinition public void display(){ System.out.println("Je suis un animal"); } } class Dog extends Animal { //Méthode de redéfinition @Override public void display(){ System.out.println("Je suis un chien"); } public void printMessage(){ display(); } } class Main { public static void main(String[] args) { Dog dog1 = new Dog(); dog1.printMessage(); } }
Résultat de la sortie
Je suis un chien
Dans cet exemple, en créant un objet de la classe Dog,1,nous pouvons appeler sa méthode printMessage(), puis cette méthode exécute la commande display().
Comme le nom l'indique, display() est déjà définie dans deux classes, donc la méthode display() de la sous-classe Dog couvre la méthode display() de la super-classe Animal. Par conséquent, la méthode de la sous-classe est appelée.
Comme son nom l'indique, l'annotation @SuppressWarnings indique au compilateur d'interdire les avertissements générés pendant l'exécution du programme.
Nous pouvons spécifier le type d'avertissement à annuler. Les avertissements qui peuvent être interdits sont spécifiques au compilateur, mais les avertissements sont divisés en deux catégories :Déprécié et Non vérifié.
Pour interdire l'affichage d'avertissements de catégories spécifiques, nous utilisons délibérément :
@SuppressWarnings("warningCategory")
Par exemple,
@SuppressWarnings("deprecated")
Pour interdire l'affichage de plusieurs catégories d'avertissements, nous utilisons délibérément :
@SuppressWarnings("warningCategory"1", "warningCategory2"})
Par exemple,
@SuppressWarnings({"deprecated", "unchecked"})
Lorsque nous utilisons des éléments non recommandés, la catégorie deprecated indique que le compilateur interdit l'affichage des avertissements.
当我们使用原始类型时,unchecked类别指示编译器禁止显示警告。
并且,未定义的警告将被忽略。例如,
@SuppressWarnings("someundefinedwarning")
class Main { @Deprecated public static void deprecatedMethod() { System.out.println("Deprecated method"); } @SuppressWarnings("deprecated") public static void main(String args[]) { Main depObj = new Main(); depObj. deprecatedMethod(); } }
Résultat de la sortie
Deprecated method
在这里,deprecatedMethod()已被标记为已弃用,使用时会发出编译器警告。通过使用@SuppressWarnings("deprecated")注解,我们可以避免编译器警告。
@SafeVarargs注解断言,带注解的方法或构造不执行它的可变参数不安全的操作(可变的参数数)。
我们只能在不能被重写的方法或构造函数上使用此注解。这是因为重写它们的方法可能会执行不安全的操作。
在Java 9之前,我们只能在final或static方法上使用此注解,因为它们不能被重写。现在,我们也可以将此注解用于私有方法。
import java.util.*; class Main { private void displayList(List<String>... lists) { for (List<String> list : lists) { System.out.println(list); } } public static void main(String args[]) { Main obj = new Main(); List<String> universityList = Arrays.asList("Tribhuvan University", "Kathmandu University"); obj.displayList(universityList); List<String> programmingLanguages = Arrays.asList("Java", "C"); obj.displayList(universityList, programmingLanguages); } }
Avertissements
Sécurité de type : Pollution potentielle du tas via les listes de paramètres varargs Sécurité de type : Un tableau générique de List<String> est créé pour un varargs paramètre
Résultat de la sortie
Note : Main.java utilise des opérations non vérifiées ou non sécurisées. [Université Tribhuvan, Université Kathmandu] [Université Tribhuvan, Université Kathmandu] [Java, C]
Ici, List ... list spécifie le type de List pour les arguments variables. Cela signifie que la méthode displayList() peut avoir zéro ou plusieurs paramètres.
Le programme précédent compile sans erreur, mais génère un avertissement lorsqu'il n'est pas utilisé l'annotation @SafeVarargs.
Lors de l'utilisation de l'annotation @SafeVarargs dans l'exemple précédent,
@SafeVarargs private void displayList(List<String>... lists) { ... }
Nous obtenons le même résultat, mais sans aucun avertissement. Lorsque cette annotation est utilisée, les avertissements non vérifiés sont également supprimés.
Java 8Tout d'abord, nous avons introduit cette annotation @FunctionalInterface. Cette annotation indique que le type utilisant cette annotation est une interface fonctionnelle. Une interface fonctionnelle ne peut avoir qu'une seule méthode abstraite.
@FunctionalInterface public interface MyFuncInterface{ public void firstMethod(); //C'est une méthode abstraite }
Si nous ajoutons une autre méthode abstraite, alors
@FunctionalInterface public interface MyFuncInterface{ public void firstMethod(); // C'est une méthode abstraite public void secondMethod(); //Cela entraînera une erreur de compilation }
Maintenant, lorsque nous exécutons le programme, nous recevons les avertissements suivants :
Annotation @FunctionalInterface inattendue @FunctionalInterface ^ MyFuncInterface n'est pas une interface fonctionnelle multiples non-redéfinissant les méthodes abstraites trouvées dans l'interface MyFuncInterface
L'utilisation de l'annotation @FunctionalInterface n'est pas obligatoire. Le compilateur considère toute interface qui satisfait la définition de l'interface fonctionnelle comme une interface fonctionnelle.
L'objectif de cette annotation est de s'assurer que l'interface fonctionnelle n'a qu'une seule méthode abstraite.
Mais elle peut avoir un nombre illimité de méthodes par défaut et statiques, car elles sont toutes implémentées.
@FunctionalInterface public interface MyFuncInterface{ public void firstMethod(); //C'est une méthode abstraite default void secondMethod() { ... } default void thirdMethod() { ... } }
Nous pouvons également créer nos propres annotations personnalisées.
sa syntaxe est :
[Spécificateur d'accès] @interface<NomAnnotation> { DataType <MethodName>() [valeur par défaut]; }
Voici les informations que vous devez connaître sur les annotations personnalisées :
Les annotations peuvent être créées en utilisant @interface suivi du nom de l'annotation.
Les annotations peuvent avoir des éléments qui ressemblent à des méthodes, mais elles ne sont pas implémentées.
La valeur par défaut est optionnelle. Les paramètres ne peuvent pas être null.
Le type de retour de la méthode peut être de base, une énumération, une chaîne, un nom de classe ou un tableau de ces types.
@interface MyCustomAnnotation { String value() default "default value"; } class Main { @MyCustomAnnotation(value = "w3codebox) public void method1() { System.out.println("Méthode de test1"); } public static void main(String[] args) throws Exception { Main obj = new Main(); obj.method1(); } }
Résultat de la sortie
Méthode de test1
Les annotations de métadonnées sont des annotations appliquées à d'autres annotations.
L'annotation @Retention spécifie le niveau le plus élevé auquel l'annotation est disponible.
sa syntaxe est :
@Retention(RetentionPolicy)
Il y a trois types :
RetentionPolicy.SOURCE - Les annotations ne sont disponibles qu'au niveau source et sont ignorées par le compilateur.
RetentionPolicy.CLASS - L'annotation est disponible pour l'éditeur de compilation à la compilation, mais le Java Virtual Machine (JVM) l'ignore.
RetentionPolicy.RUNTIME - L'annotation peut être utilisée par le JVM.
Par exemple,
@Retention(RetentionPolicy.RUNTIME) public @interface MyCustomAnnotation{ ... }
Par défaut, les annotations personnalisées ne sont pas incluses dans la documentation officielle Java. Pour inclure l'annotation dans la documentation Javadoc, utilisez l'annotation @Documented.
Par exemple,
@Documented public @interface MyCustomAnnotation{ ... }
Nous pouvons utiliser l'annotation @Target pour limiter l'annotation à l'application à des cibles spécifiques.
sa syntaxe est :
@Target(ElementType)
ElementType peut être l'un des types suivants :
Type d'élément | Target |
---|---|
ElementType.ANNOTATION_TYPE | Type d'annotation |
ElementType.CONSTRUCTOR | Constructeur |
ElementType.FIELD | Champ |
ElementType.LOCAL_VARIABLE | Variable locale |
ElementType.METHOD | Méthode |
ElementType.PACKAGE | Paquet |
ElementType.PARAMETER | Paramètres |
ElementType.TYPE | Utilisé pour décrire la déclaration de classe, interface (y compris le type d'annotation) ou enum |
Par exemple,
@Target(ElementType.METHOD) public @interface MyCustomAnnotation{ ... }
Dans cet exemple, nous limitons l'utilisation de cette annotation aux méthodes.
Remarque :Si le type de cible n'est pas défini, l'annotation peut être appliquée à n'importe quel élément.
Par défaut, le type d'annotation ne peut pas être hérité de la classe parente. Cependant, si nécessaire pour hériter l'annotation de la classe parente à la classe fille, on peut utiliser l'annotation @Inherited.
sa syntaxe est :
@Inherited
Par exemple,
@Inherited public @interface MyCustomAnnotation { ... } @MyCustomAnnotation public class ParentClass{ ... } public class ChildClass extends ParentClass { ... }
Les annotations marquées par @Repeatable peuvent être appliquées plusieurs fois au même déclaration.
@Repeatable(Universities.class)} public @interface University { String name(); }
The value defined in the @Repeatable annotation is a container annotation. Container annotations have the variable values (value) of the above repeatable annotation array type. Here, Universities is the container of annotation types.
public @interface Universities { University[] value(); }
Now, the @University annotation can be used multiple times on the same declaration.
@University(name = "TU") @University(name = "KU") private String uniName;
If you need to retrieve annotation data, you can useReflection.
To retrieve annotation values, we use the getAnnotationsByType() or getAnnotations() method defined in the reflection API.