Revisit nullability annotations
This commit introduces the following changes. 1) It adds a new Spring @NonNull annotation which allows to apply @NonNullApi semantic on a specific element, like @Nullable does. Combined with @Nullable, it allows partial null-safety support when package granularity is too broad. 2) @Nullable and @NonNull can apply to ElementType.TYPE_USE in order to be used on generic type arguments (SPR-15942). 3) Annotations does not apply to ElementType.TYPE_PARAMETER anymore since it is not supported yet (applicability for such use case is controversial and need to be discussed). 4) @NonNullApi does not apply to ElementType.FIELD anymore since in a lot of use cases (private, protected) it is not part for the public API + its usage should remain opt-in. A dedicated @NonNullFields annotation has been added in order to set fields default to non-nullable. 5) Updated Javadoc and reference documentation. Issue: SPR-15756
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
* annotations with attribute overrides.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.core.annotation;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
@@ -4,6 +4,8 @@
|
||||
* between a reactive stream of bytes and Java objects.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.core.codec;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* SPI to implement Converters for the type conversion system.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.core.convert.converter;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* Type conversion system API.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.core.convert;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* Default implementation of the type conversion system.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.core.convert.support;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* profile and hierarchical property source support.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.core.env;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* Generic abstraction for working with byte buffer implementations.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.core.io.buffer;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* Generic abstraction for (file-based) resources, used throughout the framework.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.core.io;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* Includes a ResourcePatternResolver mechanism.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.core.io.support;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* and other core helpers that are not specific to any part of the framework.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.core;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
* Includes exceptions for serialization and deserialization failures.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.core.serializer;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* Includes adapters to the Converter SPI.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.core.serializer.support;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* Support for styling values as Strings, with ToStringCreator as central class.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.core.style;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* and provides SyncTaskExecutor and SimpleAsyncTaskExecutor implementations.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.core.task;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* Includes an adapter for the standard ExecutorService interface.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.core.task.support;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* Support classes for reading annotation and class-level metadata.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.core.type.classreading;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* Core support package for type filtering (e.g. for classpath scanning).
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.core.type.filter;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* Core support package for type introspection.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.core.type;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.lang;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.meta.TypeQualifierNickname;
|
||||
|
||||
/**
|
||||
* A common Spring annotation to declare that annotated elements cannot be {@code null}.
|
||||
* Leverages JSR 305 meta-annotations to indicate nullability in Java to common tools with
|
||||
* JSR 305 support and used by Kotlin to infer nullability of Spring API.
|
||||
*
|
||||
* <p>Should be used at generic type argument, parameter, return value, and field level.
|
||||
* Methods overrides should repeat parent {@code @NonNull} annotations unless they behave
|
||||
* differently.
|
||||
*
|
||||
* <p>Use {@code @NonNullApi} (scope = parameters + return values) and/or {@code @NonNullFields}
|
||||
* (scope = fields) to set the default behavior to non-nullable in order to avoid annotating
|
||||
* your whole codebase with {@code @NonNull}. No default retricted to generic type argument
|
||||
* is possible ({@code ElementType.TYPE_USE} scope is too wide) so each generic type argument
|
||||
* needs to be annotated with @code @NonNull}.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Juergen Hoeller
|
||||
* @since 5.0
|
||||
* @see NonNullApi
|
||||
* @see NonNullFields
|
||||
* @see Nullable
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE_USE, ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Nonnull
|
||||
@TypeQualifierNickname
|
||||
public @interface NonNull {
|
||||
}
|
||||
@@ -26,25 +26,30 @@ import javax.annotation.meta.TypeQualifierDefault;
|
||||
|
||||
/**
|
||||
* A common Spring annotation to declare that parameters and return values
|
||||
* are to be considered as non-nullable by default for a given package,
|
||||
* along with their underlying fields.
|
||||
* are to be considered as non-nullable by default for a given package.
|
||||
* Leverages JSR 305 meta-annotations to indicate nullability in Java to common tools with
|
||||
* JSR 305 support and used by Kotlin to infer nullability of Spring API.
|
||||
*
|
||||
*
|
||||
* <p>Should be used at package level in association with {@link Nullable}
|
||||
* annotations at parameter and return value level.
|
||||
*
|
||||
* <p>Leverages JSR-305 meta-annotations to indicate its semantics to
|
||||
* common tools with JSR-305 support.
|
||||
* <p>This annotation does not define nullability of generic type arguments, because
|
||||
* {@code @TypeQualifierDefault(ElementType.TYPE_USE)} scope would be too broad.
|
||||
* As a consequence, each API generic type argument should be annotated
|
||||
* with {@link Nullable} or {@link NonNull} to specify their nullability.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Juergen Hoeller
|
||||
* @since 5.0
|
||||
* @see NonNullFields
|
||||
* @see Nullable
|
||||
* @see javax.annotation.Nonnull
|
||||
* @see NonNull
|
||||
*/
|
||||
@Target(ElementType.PACKAGE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Nonnull
|
||||
@TypeQualifierDefault({ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE_PARAMETER, ElementType.FIELD})
|
||||
@TypeQualifierDefault({ElementType.METHOD, ElementType.PARAMETER})
|
||||
public @interface NonNullApi {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.lang;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.meta.TypeQualifierDefault;
|
||||
|
||||
/**
|
||||
* A common Spring annotation to declare that fields are to be considered as
|
||||
* non-nullable by default for a given package. Leverages JSR 305 meta-annotations to
|
||||
* indicate nullability in Java to common tools with JSR 305 support and used by Kotlin
|
||||
* to infer nullability of Spring API.
|
||||
*
|
||||
* <p>Should be used at package level in association with {@link Nullable}
|
||||
* annotations at field level.
|
||||
*
|
||||
* <p>This annotation does not define nullability of generic type arguments, because
|
||||
* {@code @TypeQualifierDefault(ElementType.TYPE_USE)} scope would be too broad.
|
||||
* As a consequence, each field generic type argument should be annotated
|
||||
* with {@link Nullable} or {@link NonNull} to specify their nullability.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @since 5.0
|
||||
* @see NonNullFields
|
||||
* @see Nullable
|
||||
* @see NonNull
|
||||
*/
|
||||
@Target(ElementType.PACKAGE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Nonnull
|
||||
@TypeQualifierDefault(ElementType.FIELD)
|
||||
public @interface NonNullFields {
|
||||
}
|
||||
@@ -26,23 +26,25 @@ import javax.annotation.meta.TypeQualifierNickname;
|
||||
import javax.annotation.meta.When;
|
||||
|
||||
/**
|
||||
* A common Spring annotation to declare that the annotated parameter,
|
||||
* return value or field could be {@code null} under some circumstances.
|
||||
* A common Spring annotation to declare that annotated elements can be {@code null} under
|
||||
* some circumstance. Leverages JSR 305 meta-annotations to indicate nullability in Java
|
||||
* to common tools with JSR 305 support and used by Kotlin to infer nullability of Spring API.
|
||||
*
|
||||
* <p>Should be used at parameters, return values and optionally field level in association
|
||||
* with {@link NonNullApi} package-level annotations. Methods overrides should repeat parent
|
||||
* parameter or return value {@code @Nullable} annotations unless they behave differently.
|
||||
* <p>Should be used at generic type argument, parameter, return value, and field level.
|
||||
* Methods overrides should repeat parent {@code @Nullable} annotations unless they behave
|
||||
* differently.
|
||||
*
|
||||
* <p>Leverages JSR-305 meta-annotations to indicate its semantics to
|
||||
* common tools with JSR-305 support.
|
||||
* <p>Can be used in association with {@code NonNullApi} or {@code @NonNullFields} to
|
||||
* override the default non-nullable semantic to nullable.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
* @author Juergen Hoeller
|
||||
* @since 5.0
|
||||
* @see NonNullApi
|
||||
* @see javax.annotation.Nullable
|
||||
* @see NonNullFields
|
||||
* @see NonNull
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE_PARAMETER, ElementType.FIELD})
|
||||
@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE_USE, ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Nonnull(when = When.MAYBE)
|
||||
|
||||
@@ -3,5 +3,6 @@
|
||||
* Used descriptively within the framework codebase; validated by Animal Sniffer at build time.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.lang;
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* A generic back-off abstraction.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.util.backoff;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* such as an invertible comparator and a compound comparator.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.util.comparator;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* Useful generic {@code java.util.concurrent.Future} extension.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.util.concurrent;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* a Log4J configurer, and a state holder for paged lists of objects.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.util;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* such as error handlers that log warnings via Commons Logging.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.util.xml;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
||||
|
||||
Reference in New Issue
Block a user