A partir de la versión 5.0 de Spring tendremos una nueva anotación que nos ayudara según mi opinión a escribir código mucho mas estable. Lo podríamos tomar como una medida de seguridad que podemos tomar para revisar que nuestro código no tenga potenciales referencias a nulos y obtener la tan temida y conocida NullPointerException.
@NonNull es una anotación común de Spring que declara que los métodos anotados no pueden dar como resultado null. Se basa en la especificación JSR-305 para indicar anulabilidad en las herramientas comunes de java y es usado por Kotlin para inferir la anulabilidad de un componente en la API de Spring.
Puede ser usado en los siguientes escenarios:
- Parámetros
- Valores de retorno
- Campos
De este modo todos los métodos que sean un @Override de un método anotado como @NonNull debe repetir la anotación a menos que el método en cuestión se comporte de manera diferente.
Ademas se pone a nuestra disposición anotaciones mas especificas como @NonNullApi y @NonNullFields que eventualmente podrían ahorrarnos refactorizar código.
Por ejemplo, definamos una clase Persona:
public class Persona { private String nombre; void setNombre(String nombre) { if (nombre != null && nombre.isEmpty()) { nombre = null; } this.nombre = nombre; } }
Es una clase perfectamente valida pero, tiene el defecto de que si el nombre esta vacío entonces podríamos encontrarnos con un NullPointerException por cualquiera que ocupe de ella.
Entonces la anotación @NonNull nos ofrece una mejor visibilidad en este tipo de casos, al darnos una advertencia en tiempo de compilación, y si usan in IDE avanzado como IntelliJ incluso en el momento en que escribimos el código nos advertirá que nombre = null; es una violación a la regla @NonNull que hemos declarado arriba.
Todo lo que tenemos que hacer es anotar el campo nombre de esta manera:
@NonNull private String nombre;
Viendo bugs antes de que compilen….
La anotación @NonNullFields nos permite declarar a nivel de paquete que todos los campos de ese paquete son NonNull. y para que funcione hay que crear un archivo llamado package-info.java en el directorio raíz del paquete y anotarlo así:
@NonNullFields package com.ricardogeek.nonnullfields;
y de esa manera Spring infiere que todos los campos declarados en las clases de ese paquete son obligatorios. Hay que resaltar que esto no hará que nuestra compilación falle, si no que, mas bien nos dará una advertencia de que estamos cometiendo un error asignando null a un campo que no puede ser null 🙂
De forma similar a esto tenemos el @NonNullApi nos asegura que todos los métodos en un paquete retornan algo que no es null, y en package-info.java podemos anotarlo de forma similar a lo anterior:
@NonNullApi package com.ricardogeek.nonnullapi;
Esta anotación nos advierte de un posible bug cuando escribimos código como este:
package com.ricardogeek.nonnullapi; public class Persona { @Nullable private String apodo; String getApodo() { return apodo; } }
En este caso se detecta que el package-info.java tiene la anotación @NonNullApi y nos advierte que return apodo; esta violando la restricción de que la API de ese paquete no puede regresar nulos.
Conclusión
Es importante recordar que estas anotaciones solo son útiles en ambientes de desarrollo que las soporten, y nos ayudan a escribir mejor código y darnos cuenta de posibles bugs con antelación. No obstante no harán que falle la compilación si se violan o no provocaran un fallo al momento de correr.