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:
@@ -31,3 +31,5 @@ include::core/core-aop.adoc[leveloffset=+1]
|
||||
|
||||
include::core/core-aop-api.adoc[leveloffset=+1]
|
||||
|
||||
include::core/core-null-safety.adoc[leveloffset=+1]
|
||||
|
||||
|
||||
53
src/docs/asciidoc/core/core-null-safety.adoc
Normal file
53
src/docs/asciidoc/core/core-null-safety.adoc
Normal file
@@ -0,0 +1,53 @@
|
||||
[[null-safety]]
|
||||
= Null-safety
|
||||
|
||||
Although Java does not allow to express null-safety with its type system, Spring Framework
|
||||
now provides annotations declared in the `org.springframework.lang` package to declare
|
||||
nullability of APIs and fields.
|
||||
|
||||
Spring Framework leverages these annotations, but they can also be used in any Spring based
|
||||
Java project to declare null-safe APIs and optionally null-safe fields. Nullability of
|
||||
types used inside method bodies is outside of the scope of this feature.
|
||||
|
||||
These annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]
|
||||
annotations (a dormant JSR but supported by tools like IntelliJ IDEA) to provide useful
|
||||
warnings to Java developers related to null-safety in order to avoid `NullPointerException`
|
||||
at runtime. JSR 305 meta-annotations allows tooling vendors to provide null-safety support
|
||||
in a generic way, without having to hard-code support for Spring annotations.
|
||||
|
||||
They are also used by Kotlin which supports natively
|
||||
https://kotlinlang.org/docs/reference/null-safety.html[null-safety]. By default, types from
|
||||
Java APIs used in Kotlin are recognized as
|
||||
https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types[platform types]
|
||||
for which null-checks are relaxed.
|
||||
https://github.com/Kotlin/KEEP/blob/jsr-305/proposals/jsr-305-custom-nullability-qualifiers.md[Kotlin support for JSR 305 annotations]
|
||||
+ Spring nullability annotations provide null-safety for the whole Spring Framework API to Kotlin developers,
|
||||
with the advantage of dealing with `null` related issues at compile time rather than bumping into the famous
|
||||
`NullPointerException` at runtime. More details are available in <<kotlin#null-safety,Kotlin support documentation>>.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Other libraries like Reactor or Spring Data leverage these annotations as well to provide
|
||||
null-safe APIs.
|
||||
====
|
||||
|
||||
The following annotations are provided:
|
||||
|
||||
* {api-spring-framework}/lang/NonNull.html[`@NonNull`] annotation where specific parameter,
|
||||
return value, generic type argument, varargs element, array element or field cannot be `null`
|
||||
(not needed on parameter and return value where `@NonNullApi` and `@NonNullFields` applies) .
|
||||
* {api-spring-framework}/lang/Nullable.html[`@Nullable`] annotation where specific
|
||||
parameter, return value, generic type argument, varargs element, array element or field
|
||||
can be `null`.
|
||||
* {api-spring-framework}/lang/NonNullApi.html[`@NonNullApi`] annotation at package level
|
||||
declares non-null as the default behavior for parameters and return values.
|
||||
* {api-spring-framework}/lang/NonNullFields.html[`@NonNullFields`] annotation at package
|
||||
level declares non-null as the default behavior for fields.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Generic type arguments, varargs and array elements are out of the scope of `@NonNullApi`
|
||||
and `@NonNullFields`, because `@TypeQualifierDefault(ElementType.TYPE_USE)` would apply to
|
||||
a lot of other use cases. As a consequence, nullability for such elements need to be specified
|
||||
explicitly with `@NonNull` and `@Nullable`.
|
||||
====
|
||||
@@ -5,6 +5,7 @@
|
||||
:toc: left
|
||||
:toclevels: 2
|
||||
|
||||
[[introduction]]
|
||||
== Introduction
|
||||
|
||||
https://kotlinlang.org[Kotlin] is a statically-typed language targeting the JVM (and other platforms)
|
||||
@@ -15,6 +16,7 @@ existing libraries written in Java.
|
||||
Spring Framework 5 introduces first-class support for Kotlin and allows developers to write
|
||||
Spring + Kotlin applications almost as if the Spring Framework was a native Kotlin framework.
|
||||
|
||||
[[requirements]]
|
||||
== Requirements ==
|
||||
|
||||
Spring Framework supports Kotlin 1.1+ and requires
|
||||
@@ -25,6 +27,7 @@ and https://bintray.com/bintray/jcenter/org.jetbrains.kotlin%3Akotlin-reflect[`k
|
||||
to be present on the classpath. They are provided by default if one bootstraps a Kotlin project on
|
||||
https://start.spring.io/#!language=kotlin[start.spring.io].
|
||||
|
||||
[[extensions]]
|
||||
== Extensions
|
||||
|
||||
Thanks to its great https://kotlinlang.org/docs/reference/java-interop.html[Java interoperability]
|
||||
@@ -74,6 +77,7 @@ val users : Flux<User> = client.get().retrieve().bodyToFlux()
|
||||
As in Java, `users` in Kotlin is strongly typed, but Kotlin's clever type inference allows
|
||||
for a shorter syntax.
|
||||
|
||||
[[null-safety]]
|
||||
== Null-safety
|
||||
|
||||
One of Kotlin's key features is https://kotlinlang.org/docs/reference/null-safety.html[null-safety]
|
||||
@@ -84,21 +88,15 @@ declarations and expressing "value or no value" semantics without paying the cos
|
||||
http://www.baeldung.com/kotlin-null-safety[comprehensive guide to Kotlin null-safety].)
|
||||
|
||||
Although Java does not allow one to express null-safety in its type-system, Spring Framework now
|
||||
provides https://jira.spring.io/browse/SPR-15540[null-safety of the whole Spring Framework API]
|
||||
via tooling-friendly annotations:
|
||||
|
||||
* `@NonNullApi` annotations at package level declare non-null as the default behavior
|
||||
* `@Nullable` annotations where specific parameters or return values can be `null`.
|
||||
|
||||
Both annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]
|
||||
annotations (a dormant JSR but supported by tools like IDEA, Findbugs, etc.)
|
||||
to provide useful warnings to Java developers.
|
||||
|
||||
On the Kotlin side - as of https://blog.jetbrains.com/kotlin/2017/08/kotlin-1-1-4-is-out/[Kotlin 1.1.4 release] -
|
||||
these annotations https://github.com/Kotlin/KEEP/blob/jsr-305/proposals/jsr-305-custom-nullability-qualifiers.md[are recognized by Kotlin]
|
||||
in order to provide null-safety for the whole Spring Framework API. That means
|
||||
one should never experience a `NullPointerException` when using Spring Framework and Kotlin because
|
||||
the compiler will not allow it.
|
||||
provides <<core#null-safety,null-safety of the whole Spring Framework API>>
|
||||
via tooling-friendly annotations declared in the `org.springframework.lang` package.
|
||||
By default, types from Java APIs used in Kotlin are recognized as
|
||||
https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types[platform types]
|
||||
for which null-checks are relaxed.
|
||||
https://github.com/Kotlin/KEEP/blob/jsr-305/proposals/jsr-305-custom-nullability-qualifiers.md[Kotlin support for JSR 305 annotations]
|
||||
available as of https://blog.jetbrains.com/kotlin/2017/08/kotlin-1-1-4-is-out/[1.1.4 release]
|
||||
+ Spring nullability annotations provide null-safety for the whole Spring Framework API to Kotlin developers,
|
||||
with the advantage of dealing with `null` related issues at compile time.
|
||||
|
||||
For now, one needs to use a `-Xjsr305-annotations=enable` flag (specified via the
|
||||
`freeCompilerArgs` property with Maven or Gradle Kotlin plugins), but that should become
|
||||
@@ -109,10 +107,11 @@ until Kotlin 1.1.5 is released (it will fix https://youtrack.jetbrains.com/issue
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Other libraries like Reactor and Spring Data leverage these annotations to provide
|
||||
Other libraries like Reactor and Spring Data leverage these annotations as well to provide
|
||||
null-safe APIs for Kotlin developers.
|
||||
====
|
||||
|
||||
[[classes-interfaces]]
|
||||
== Classes & Interfaces
|
||||
|
||||
Spring Framework supports various Kotlin constructs like instantiating Kotlin classes
|
||||
@@ -133,6 +132,7 @@ detected without the Jackson Kotlin module present.
|
||||
As of Spring Boot 2.0, Jackson Kotlin module is automatically provided via the JSON starter.
|
||||
====
|
||||
|
||||
[[annotations]]
|
||||
== Annotations
|
||||
|
||||
Spring Framework also takes advantage of https://kotlinlang.org/docs/reference/null-safety.html[Kotlin null-safety]
|
||||
@@ -146,6 +146,7 @@ to determine if a bean is required or not. `@Autowired lateinit var foo: Foo` im
|
||||
of type `Foo` must be registered in the application context while `@Autowired lateinit var foo: Foo?`
|
||||
won’t raise an error if such bean does not exist.
|
||||
|
||||
[[bean-definition-dsl]]
|
||||
== Bean definition DSL
|
||||
|
||||
Spring Framework 5 introduces a new way to register beans in a functional way using lambdas
|
||||
@@ -247,6 +248,7 @@ see https://stackoverflow.com/questions/45935931/how-to-use-functional-bean-defi
|
||||
for more details and up-to-date information.
|
||||
====
|
||||
|
||||
[[web]]
|
||||
== Web
|
||||
|
||||
=== WebFlux Functional DSL
|
||||
@@ -321,6 +323,7 @@ ${include("footer")}
|
||||
See https://github.com/sdeleuze/kotlin-script-templating[kotlin-script-templating] example
|
||||
project for more details.
|
||||
|
||||
[[spring-projects-in-kotlin]]
|
||||
== Spring projects in Kotlin
|
||||
|
||||
This section provides a focus on some specific hints and recommendations worth
|
||||
@@ -532,6 +535,7 @@ class IntegrationTests {
|
||||
}
|
||||
----
|
||||
|
||||
[[getting-started]]
|
||||
== Getting started
|
||||
|
||||
=== start.spring.io
|
||||
@@ -554,6 +558,7 @@ Kotlin DSL.
|
||||
For other use cases, Spring MVC and its annotation-based programming model is a perfectly
|
||||
valid and fully supported choice.
|
||||
|
||||
[[resources-started]]
|
||||
== Resources
|
||||
|
||||
* http://kotlinlang.org/docs/reference/[Kotlin language reference]
|
||||
|
||||
Reference in New Issue
Block a user