Annotazioni Spring Null-Safety

1. Panoramica

A partire dalla primavera 5, ora abbiamo accesso a un'interessante funzionalità che ci aiuta a scrivere codice più sicuro. Questa funzionalità è chiamata null-safety, un gruppo di annotazioni che funziona come una protezione che controlla potenziali riferimenti nulli.

Piuttosto che lasciarci farla franca con codice non sicuro, la funzionalità di sicurezza nulla produce avvisi in fase di compilazione. Tali avvisi possono impedire le eccezioni catastrofiche del puntatore nullo (NPE) in fase di esecuzione.

2. L' annotazione @NonNull

L' annotazione @NonNull è la più importante tra tutte le annotazioni della funzione di sicurezza nulla. Possiamo usare questa annotazione per dichiarare un vincolo non nullo ovunque sia previsto un riferimento a un oggetto: un campo, un parametro di metodo o il valore restituito da un metodo.

Supponiamo di avere una classe denominata Persona :

public class Person { private String fullName; void setFullName(String fullName) { if (fullName != null && fullName.isEmpty()) { fullName = null; } this.fullName = fullName; } // getter }

Questa definizione di classe è valida, ma presenta un difetto: il campo fullName può essere impostato su null . Se ciò accade, potremmo ritrovarci con un NPE quando lavoriamo con fullName .

La funzione Spring null-safety consente agli strumenti di segnalare un tale pericolo. Ad esempio, se scriviamo codice in IntelliJ IDEA e decoriamo il campo fullName con l' annotazione @NonNull , vedremo un avviso:

Grazie a questa indicazione, siamo a conoscenza del problema in anticipo e in grado di intraprendere le azioni appropriate per evitare un errore di runtime.

3. L' annotazione @NonNullFields

L' annotazione @NonNull è utile per garantire la sicurezza nulla. Tuttavia, inquineremmo l'intera base di codice se adornassimo tutti i campi non nulli con questa annotazione.

Possiamo evitare l'abuso di @NonNull con un'altra annotazione - @NonNullFields . Questa annotazione è applicabile a livello di pacchetto, notificando ai nostri strumenti di sviluppo che tutti i campi nel pacchetto annotato sono, per impostazione predefinita, non nulli.

Affinché l' annotazione @NonNullFields si attivi , è necessario creare un file denominato package-info.java nella directory principale del pacchetto e annotare il pacchetto con @NonNullFields :

@NonNullFields package org.baeldung.nullibility;

Dichiariamo un'altra proprietà nella classe Person , chiamata nickName :

package org.baeldung.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 }

Questa volta, non abbelliamo il campo nickName con @NonNull ma vediamo comunque un avvertimento simile:

L' annotazione @NonNullFields rende il nostro codice meno dettagliato pur garantendo lo stesso livello di sicurezza fornito da @NonNull .

4. L' annotazione @Nullable

L' annotazione @NonNullFields è generalmente preferibile a @NonNull poiché aiuta a ridurre il boilerplate. A volte si desidera esentare alcuni campi dal vincolo non nullo specificato a livello di pacchetto.

Torniamo al campo nickName in e decoriamo con l' annotazione @Nullable :

@Nullable private String nickName;

L'avvertimento che abbiamo visto prima è sparito ora:

In questa situazione, abbiamo utilizzato l' annotazione @Nullable per sovrascrivere la semantica di @NonNullFields su un campo.

5. L' annotazione @NonNullApi

L' annotazione @NonNullFields si applica solo, come suggerisce il nome, ai campi. Se vogliamo avere lo stesso impatto sui parametri dei metodi e sui valori restituiti, avremo bisogno di @NonNullApi .

Come con @NonNullFields , dobbiamo specificare l' annotazione @NonNullApi nel file package-info.java :

@NonNullApi package org.baeldung.nullibility;

Definiamo un getter per il campo nickName :

package org.baeldung.nullibility; // import statements public class Person { @Nullable private String nickName; String getNickName() { return nickName; } // other declarations }

Con l' annotazione @NonNullApi attiva, viene emesso un avviso su un possibile valore nullo prodotto dal metodo getNickName :

Si noti che proprio come l' annotazione @NonNullFields , possiamo sovrascrivere @NonNullApi a livello di metodo con l' annotazione @Nullable .

6. Conclusione

La sicurezza nulla primaverile è una grande caratteristica che aiuta a diminuire la possibilità di NPE. Tuttavia, ci sono due punti importanti da tenere in considerazione durante l'utilizzo di questa funzione:

  • È utilizzabile solo in uno strumento di sviluppo di supporto, come IntelliJ IDEA
  • Non impone controlli nulli in fase di esecuzione: dobbiamo comunque scrivere il codice per evitare NPE

Il codice sorgente per questo tutorial può essere trovato su GitHub.