@NonNullApi and @NonNullFields are package level Spring annotations that define the default behaviour:
@NonNullApi should be used at package level in association with org.springframework.lang.Nullable annotations at parameter and return value level.
@NonNullFields should be used at package level in association with org.springframework.lang.Nullable annotations at field level.
https://docs.spring.io/spring-framework/reference/7.0-SNAPSHOT/core/null-safety.html
https://www.baeldung.com/spring-null-safety-annotations
https://stackoverflow.com/a/42695253/1323562
https://dzone.com/articles/when-to-use-jsr-305-for-nullability-in-java
Package-level annotations do not apply to subpackages
Spring null-safety annotations are only usable on some IDEs
Spring null-safety annotations do not enforce null checks at runtime (it is still needed to write code for skipping NPEs, o using other annotations)
Nullability annotations.
JSpecify
Define non-null default at package level:
@NullMarked
package org.example;
import org.jspecify.annotations.NullMarked;
Use @Nullable (regardless of the package although preferred is: org.jspecify.annotations.Nullable)
With arrays and varargs, you need to be able to differentiate the nullness of the elements from the nullness of the array itself. Pay attention to the syntax defined by the Java specification which may be initially surprising:
@Nullable Object[] array means individual elements can be null but the array itself can’t.
Object @Nullable [] array means individual elements can’t be null but the array itself can.
@Nullable Object @Nullable [] array means both individual elements and the array can be null.
JSR 303 (validation) is recognized by springdoc-openapi.
JSR 305 (defect detection) status is 'Dormant' (and unrecognized by springdoc-openapi). Implemented in dependency:
<dependency>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-annotations</artifactId>
<version>4.7.2</version>
<scope>provided</scope>
</dependency>
Previously was implemented in dependency com.google.code.findbugs:annotations:3.0.1
JSR 308 (annotations on Java types)
jakarta.annotation.Nullable
PROs: n/a
CONs: Unrecognized by Sonar v8.9.7
javax.annotation.Nullable
PROs: n/a
CONs: Former, non-jakarta
org.springframework.lang.Nullable (PREFERRED)
PROs: Spring Boot annotation
CONs: n/a
jakarta.annotation.Nonnull
PROs: Recognized by lombok @RequiredArgsConstructor
CONs: n/a
javax.annotation.Nonnull
PROs: JSR 305, Recognized by lombok @RequiredArgsConstructor
CONs: Former, non-jakarta. Unrecognized by springdoc-openapi (instead use org.springframework.lang.NonNull)
jakarta.validation.constraints.NotNull
PROs: JSR 303. Recognized by Spring Boot. Recognized by springdoc-openapi. Supported in generic type arguments (Set<@NonNull Mytype>)
CONs: Unrecognized by lombok @RequiredArgsConstructor (either use modifier 'final' or add @lombok.NonNull or add @jakarta.annotation.Nonnull)
javax.validation.constraints.NotNull
PROs: JSR 303. Recognized by Spring Boot. Recognized by springdoc-openapi. Supported in generic type arguments (Set<@NonNull Mytype>)
CONs: Unrecognized by lombok @RequiredArgsConstructor (either use modifier 'final' or add @lombok.NonNull or add @jakarta.annotation.Nonnull)
lombok.NonNull
PROs: Supported in generic type arguments (Set<@NonNull Mytype>)
CONs: n/a
org.springframework.lang.NonNull (PREFERRED)
PROs: JSR 305, Recognized by lombok @RequiredArgsConstructor & springdoc-openapi
CONs: Unsupported in generic type arguments (Set<@NonNull Mytype>)
/**
* <pre>
* (at)NonNullApi should be used at package level in association with
* org.springframework.lang.Nullable annotations at parameter and return value level.
*
* (at)NonNullFields should be used at package level in association with
* org.springframework.lang.Nullable annotations at field level.
* </pre>
*/
@NonNullApi
@NonNullFields
package edu.cou.myapp;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullFields;