Questions d’entretiens Java Annotations (+ Réponses)

Questions d'entretiens chez Java Annotations (+ Réponses)

1. introduction

Les annotations existent depuis Java 5 et, de nos jours, ce sont des constructions de programmation omniprésentes qui permettent d'enrichir le code.

Dans cet article, nous allons passer en revue certaines des questions concernant les annotations; qui sont souvent posées lors d'entretiens techniques et, le cas échéant; nous mettrons en œuvre des exemples pour mieux comprendre leurs réponses.

2. Des questions

Q1. Que sont les annotations? Quels sont leurs cas d'utilisation typiques?

Les annotations sont des métadonnées liées à des éléments du code source d'un programme et n'ont aucun effet sur le fonctionnement du code qu'elles exploitent.

Leurs cas d'utilisation typiques sont:

  • Information for the compiler - avec des annotations, le compilateur peut détecter les erreurs ou supprimer les avertissements

  • Compile-time and deployment-time processing - les outils logiciels peuvent traiter les annotations et générer du code, des fichiers de configuration, etc.

  • Runtime processing - les annotations peuvent être examinées à l'exécution pour personnaliser le comportement d'un programme

Q2. Décrivez quelques annotations utiles de la bibliothèque standard.

Il existe plusieurs annotations dans les packagesjava.lang etjava.lang.annotation, les plus courantes incluent, mais sans s'y limiter:

  • @Override – marque qu'une méthode est censée remplacer un élément déclaré dans une superclasse. S'il ne parvient pas à remplacer correctement la méthode, le compilateur émettra une erreur

  • @Deprecated - indique que l'élément est obsolète et ne doit pas être utilisé. Le compilateur émettra un avertissement si le programme utilise une méthode, une classe ou un champ marqué de cette annotation

  • @SuppressWarnings - indique au compilateur de supprimer les avertissements spécifiques. Plus couramment utilisé lors de l'interfaçage avec du code hérité écrit avant l'apparition des génériques

  • @FunctionalInterface - introduit dans Java 8, indique que la déclaration de type est une interface fonctionnelle et dont l'implémentation peut être fournie à l'aide d'une expression Lambda

Q3. Comment créer une annotation?

Les annotations sont une forme d'interface où le mot-cléinterface est précédé de@, et dont le corps contient des déclarationsannotation type element qui ressemblent beaucoup aux méthodes:

public @interface SimpleAnnotation {
    String value();

    int[] types();
}

Une fois l'annotation définie, vous pouvez commencer à l'utiliser via votre code:

@SimpleAnnotation(value = "an element", types = 1)
public class Element {
    @SimpleAnnotation(value = "an attribute", types = { 1, 2 })
    public Element nextElement;
}

Notez que lorsque vous fournissez plusieurs valeurs pour des éléments de tableau, vous devez les placer entre crochets.

Des valeurs par défaut peuvent éventuellement être fournies tant qu'elles sont des expressions constantes pour le compilateur:

public @interface SimpleAnnotation {
    String value() default "This is an element";

    int[] types() default { 1, 2, 3 };
}

Maintenant, vous pouvez utiliser l'annotation sans ces éléments:

@SimpleAnnotation
public class Element {
    // ...
}

Ou seulement certains d'entre eux:

@SimpleAnnotation(value = "an attribute")
public Element nextElement;

Q4. Quels types d'objets peuvent être renvoyés à partir d'une déclaration de méthode d'annotation?

Le type de retour doit être une primitive,String,Class,Enum ou un tableau de l'un des types précédents. Sinon, le compilateur générera une erreur.

Voici un exemple de code qui suit avec succès ce principe:

enum Complexity {
    LOW, HIGH
}

public @interface ComplexAnnotation {
    Class value();

    int[] types();

    Complexity complexity();
}

La compilation de l'exemple suivant échouera carObject n'est pas un type de retour valide:

public @interface FailingAnnotation {
    Object complexity();
}

Q5. Quels éléments de programme peuvent être annotés?

Les annotations peuvent être appliquées à plusieurs endroits du code source. Ils peuvent être appliqués aux déclarations de classes, de constructeurs et de champs:

@SimpleAnnotation
public class Apply {
    @SimpleAnnotation
    private String aField;

    @SimpleAnnotation
    public Apply() {
        // ...
    }
}

Méthodes et leurs paramètres:

@SimpleAnnotation
public void aMethod(@SimpleAnnotation String param) {
    // ...
}

Variables locales, y compris une boucle et des variables de ressource:

@SimpleAnnotation
int i = 10;

for (@SimpleAnnotation int j = 0; j < i; j++) {
    // ...
}

try (@SimpleAnnotation FileWriter writer = getWriter()) {
    // ...
} catch (Exception ex) {
    // ...
}

Autres types d'annotation:

@SimpleAnnotation
public @interface ComplexAnnotation {
    // ...
}

Et même les packages, via le fichierpackage-info.java:

@PackageAnnotation
package com.example.interview.annotations;

À partir de Java 8, ils peuvent également être appliqués auxuse de types. Pour que cela fonctionne, l'annotation doit spécifier une annotation@Target avec une valeur deElementType.USE:

@Target(ElementType.TYPE_USE)
public @interface SimpleAnnotation {
    // ...
}

L'annotation peut maintenant être appliquée à la création d'une instance de classe:

new @SimpleAnnotation Apply();

Type jette:

aString = (@SimpleAnnotation String) something;

Implements clause:

public class SimpleList
  implements @SimpleAnnotation List<@SimpleAnnotation T> {
    // ...
}

Et la clausethrows:

void aMethod() throws @SimpleAnnotation Exception {
    // ...
}

Q6. Existe-t-il un moyen de limiter les éléments dans lesquels une annotation peut être appliquée?

Oui, l'annotation@Target peut être utilisée à cette fin. Si nous essayons d'utiliser une annotation dans un contexte où elle n'est pas applicable, le compilateur générera une erreur.

Voici un exemple pour limiter l'utilisation de l'annotation@SimpleAnnotation aux déclarations de champ uniquement:

@Target(ElementType.FIELD)
public @interface SimpleAnnotation {
    // ...
}

Nous pouvons passer plusieurs constantes si nous voulons le rendre applicable dans plusieurs contextes:

@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PACKAGE })

Nous pouvons même faire une annotation afin qu'elle ne puisse pas être utilisée pour annoter quoi que ce soit. Cela peut s'avérer utile lorsque les types déclarés sont uniquement destinés à être utilisés en tant que type d'élément dans des annotations complexes:

@Target({})
public @interface NoTargetAnnotation {
    // ...
}

Q7. Que sont les méta-annotations?

Les annotations qui s'appliquent à d'autres annotations.

Toutes les annotations qui ne sont pas marquées de@Target, ou qui en sont marquées mais qui incluent la constanteANNOTATION_TYPE sont également des méta-annotations:

@Target(ElementType.ANNOTATION_TYPE)
public @interface SimpleAnnotation {
    // ...
}

Q8. Que sont les annotations répétitives?

Ce sont des annotations qui peuvent être appliquées plus d'une fois à la même déclaration d'élément.

Pour des raisons de compatibilité, depuis que cette fonctionnalité a été introduite dans Java 8, les annotations répétées sont stockées dans uncontainer annotation qui est automatiquement généré par le compilateur Java. Pour que le compilateur fasse cela, il faut deux étapes pour les déclarer.

Tout d'abord, nous devons déclarer une annotation répétable:

@Repeatable(Schedules.class)
public @interface Schedule {
    String time() default "morning";
}

Ensuite, nous définissons l'annotation contenant avec un élémentvalue obligatoire, et dont le type doit être un tableau du type d'annotation répétable:

public @interface Schedules {
    Schedule[] value();
}

Maintenant, nous pouvons utiliser @Schedule plusieurs fois:

@Schedule
@Schedule(time = "afternoon")
@Schedule(time = "night")
void scheduledMethod() {
    // ...
}

Q9. Comment récupérer des annotations? Quel est le lien avec sa politique de rétention?

Vous pouvez utiliser l'API Reflection ou un processeur d'annotation pour récupérer des annotations.

L'annotation@Retention et son paramètreRetentionPolicy affectent la manière dont vous pouvez les récupérer. Il y a trois constantes dans l'énumérationRetentionPolicy:

  • RetentionPolicy.SOURCE - fait que l'annotation soit rejetée par le compilateur mais les processeurs d'annotation peuvent les lire

  • RetentionPolicy.CLASS - indique que l'annotation est ajoutée au fichier de classe mais n'est pas accessible par réflexion

  • RetentionPolicy.RUNTIME - Les annotations sont enregistrées dans le fichier de classe par le compilateur et conservées par la JVM au moment de l'exécution afin qu'elles puissent être lues de manière réfléchie

Voici un exemple de code pour créer une annotation pouvant être lue au moment de l'exécution:

@Retention(RetentionPolicy.RUNTIME)
public @interface Description {
    String value();
}

Maintenant, les annotations peuvent être récupérées par réflexion:

Description description
  = AnnotatedClass.class.getAnnotation(Description.class);
System.out.println(description.value());

Un processeur d'annotations peut travailler avecRetentionPolicy.SOURCE, ceci est décrit dans l'articleJava Annotation Processing and Creating a Builder.

RetentionPolicy.CLASS est utilisable lorsque vous écrivez un analyseur de bytecode Java.

Q10. Le code suivant sera-t-il compilé?

@Target({ ElementType.FIELD, ElementType.TYPE, ElementType.FIELD })
public @interface TestAnnotation {
    int[] value() default {};
}

No. Il s'agit d'une erreur de compilation si la même constante d'énumération apparaît plus d'une fois dans une annotation@Target.

Si vous supprimez la constante dupliquée, le code à compiler correctement:

@Target({ ElementType.FIELD, ElementType.TYPE})

Q11. Est-il possible d'étendre les annotations?

No. Les annotations étendent toujours lesjava.lang.annotation.Annotation, comme indiqué dans lesJava Language Specification.

Si nous essayons d'utiliser la clauseextends dans une déclaration d'annotation, nous obtiendrons une erreur de compilation:

public @interface AnAnnotation extends OtherAnnotation {
    // Compilation error
}

Conclusion

Dans cet article, nous avons abordé certaines des questions fréquemment posées dans les entretiens techniques pour les développeurs Java concernant les annotations. Cette liste n'est en aucun cas exhaustive et doit être considérée uniquement comme le début de recherches ultérieures.

Nous, par exemple, vous souhaitons du succès dans toutes les interviews à venir.