Spring Null-Safety Annotations

Annotations de sécurité nulle au printemps

1. Vue d'ensemble

Depuis le printemps 5, nous avons maintenant accès à une fonctionnalité intéressante nous permettant d’écrire du code plus sûr. Cette fonctionnalité s'appelle null-safety, un groupe d'annotations fonctionnant comme une sauvegarde surveillant les références nulles potentielles.

Plutôt que de nous laisser sortir avec du code non sécurisé,the null-safety feature produces warnings at compile time. De tels avertissements peuvent empêcher des exceptions de pointeur nul (NPE) catastrophiques au moment de l'exécution.

2. L'annotation@NonNull

L'annotation@NonNull est la plus importante parmi toutes les annotations de la fonction de sécurité NULL. We can use this annotation t0 declare non-null constraint anywhere an object reference is expected: un champ, un paramètre de méthode ou la valeur de retour d'une méthode.

Supposons que nous ayons une classe nomméePerson:

public class Person {
    private String fullName;

    void setFullName(String fullName) {
        if (fullName != null && fullName.isEmpty()) {
            fullName = null;
        }
        this.fullName = fullName;
    }

    // getter
}

Cette définition de classe est valide, mais présente un défaut - le champfullName peut être défini surnull. Si cela se produit, nous pourrions nous retrouver avec un NPE en travaillant avecfullName.

La fonctionnalité Spring null-safety permet aux outils de signaler un tel danger. Par exemple, si nous écrivons du code dans IntelliJ IDEA et décorons le champfullName avec l'annotation@NonNull, nous verrons un avertissement:

image

Grâce à cette indication, nous sommes conscients du problème à l'avance et en mesure de prendre les mesures appropriées pour éviter une panne d'exécution.

3. L'annotation@NonNullFields

L'annotation@NonNull est utile pour garantir la sécurité nulle. Cependant, nous polluerions toute la base de code si tous les champs non nuls étaient ornés de cette annotation.

Nous pouvons éviter l'abus de@NonNull avec une autre annotation -@NonNullFields. This annotation is applicable at the package level, notifying our development tools that all fields in the annotated package are, by default, non-null.

Pour que l'annotation@NonNullFields entre en jeu, nous devons créer un fichier nommépackage-info.java dans le répertoire racine du package et annoter le package avec@NonNullFields:

@NonNullFields
package org.example.nullibility;

Déclarons une autre propriété dans la classePerson, appeléenickName:

package org.example.nullibility;

// import statements

public class Person {
    private String nickName;

    void setNickName(@Nullable String nickName) {
        if (nickName != null && nickName.isEmpty()) {
            nickName = null;
        }
        this.nickName = nickName;
    }

    // other declarations
}

Cette fois, nous n'embellissons pas le champnickName avec@NonNull mais voyons toujours une mise en garde similaire:

image

L'annotation@NonNullFields rend notre code moins verbeux tout en garantissant le même niveau de sécurité que celui fourni par@NonNull.

4. L'annotation@Nullable

L'annotation@NonNullFields est généralement préférable à@NonNull car elle permet de réduire le passe-partout. Nous souhaitons parfois exempter certains champs de la contrainte non nulle spécifiée au niveau du package.

Revenons au champnickName dans et décorons-le avec l'annotation@Nullable:

@Nullable
private String nickName;

L'avertissement que nous avons vu auparavant est parti maintenant:

image

Dans cette situation,we used the @Nullable annotation to override the semantics of @NonNullFields on a field.

5. L'annotation@NonNullApi

L'annotation@NonNullFields s'applique uniquement aux champs, comme son nom l'indique. If we want to have the same impact on the methods' parameters and return values, we’ll need @NonNullApi.

Comme pour@NonNullFields, nous devons spécifier l'annotation@NonNullApi dans le fichierpackage-info.java:

@NonNullApi
package org.example.nullibility;

Définissons un getter pour le champnickName:

package org.example.nullibility;

// import statements

public class Person {
    @Nullable
    private String nickName;

    String getNickName() {
        return nickName;
    }

    // other declarations
}

Avec l'annotation@NonNullApi en vigueur, un avertissement est émis concernant une éventuelle valeurnull produite par la méthodegetNickName:

image

Notez que tout comme l'annotation@NonNullFields, nous pouvons remplacer les@NonNullApi au niveau de la méthode avec l'annotation@Nullable.

6. Conclusion

Spring null-safety est une fonctionnalité intéressante qui permet de réduire les risques de NPE. Cependant, nous devons nous méfier de deux points importants lors de l'utilisation de cette fonctionnalité:

  • Il n'est utilisable que dans un outil de développement de support, tel qu'IntelliJ IDEA

  • Il n'applique pas les vérifications denull lors de l'exécution - nous devons toujours écrire du code nous-mêmes pour éviter les NPE

Le code source de ce didacticiel se trouveover on GitHub.