Seguridad frente a nulos en Spring con JSpecify
Spring 7 adopta las anotaciones JSpecify, haciendo que no-nulo sea el valor por defecto y reduciendo el ruido de anotaciones.
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
public class UserService {
@Nullable
public User findById(@NonNull String id) {
return repository.findById(id).orElse(null);
}
@NonNull
public List<User> findAll() {
return repository.findAll();
}
@NonNull
public User save(@NonNull User user) {
return repository.save(user);
}
}
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
@NullMarked
public class UserService {
public @Nullable User findById(String id) {
return repository.findById(id).orElse(null);
}
public List<User> findAll() {
return repository.findAll();
}
public User save(User user) {
return repository.save(user);
}
}
No-nulo por defecto
@NullMarked hace que todos los tipos no anotados sean no-nulos, así solo las excepciones anulables necesitan anotación.
Estándar del ecosistema
Las anotaciones JSpecify son un estándar multi-framework reconocido por NullAway, Error Prone e IDEs.
Herramientas más potentes
Los analizadores estáticos modernos entienden el modelo de nulos de JSpecify y reportan violaciones en tiempo de compilación.
Disponible desde Spring Framework 7.0 (requiere Java 17+)
Spring 5 y 6 introdujeron sus propias anotaciones de seguridad frente a nulos en el paquete `org.springframework.lang`. Aunque útiles, eran específicas del framework y requerían anotar cada elemento no-nulo explícitamente. Spring 7 migra a JSpecify, un estándar multi-ecosistema para seguridad frente a nulos. La anotación `@NullMarked` a nivel de clase o paquete declara que todos los tipos no anotados son no-nulos por defecto. Solo los tipos realmente anulables necesitan la anotación `@Nullable`, reduciendo drásticamente la verbosidad. Las anotaciones JSpecify son reconocidas por las principales herramientas de análisis estático como NullAway, Error Prone e IntelliJ IDEA, aportando un soporte de herramientas más rico que el que proporcionaban las anotaciones específicas de Spring.