Skip to content

Commit 1115be5

Browse files
committed
Add primitive type support to Nullness
See gh-34261
1 parent d83be7c commit 1115be5

File tree

5 files changed

+31
-6
lines changed

5 files changed

+31
-6
lines changed

framework-docs/modules/ROOT/pages/core/null-safety.adoc

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ annotations such as IntelliJ IDEA or Eclipse) and Kotlin where JSpecify annotati
1313
{kotlin-docs}/null-safety.html[Kotlin's null safety].
1414

1515
The {spring-framework-api}/core/Nullness.html[`Nullness` Spring API] can be used at runtime to detect the nullness of a
16-
type usage, a field, a method return type or a parameter. It provides full support for JSpecify annotations and
17-
Kotlin null safety, as well as a pragmatic check on any `@Nullable` annotation (regardless of the package).
16+
type usage, a field, a method return type or a parameter. It provides full support for JSpecify annotations,
17+
Kotlin null safety, Java primitive types, as well as a pragmatic check on any `@Nullable` annotation (regardless of the
18+
package).
1819

1920
[[null-safety-libraries]]
2021
== Annotating libraries with JSpecify annotations

spring-core/src/main/java/org/springframework/core/Nullness.java

+8-4
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,17 @@
4141
*
4242
* <p>The nullness applies to a type usage, a field, a method return type or a parameter.
4343
* <a href="https://jspecify.dev/docs/user-guide/">JSpecify annotations</a> are fully supported, as well as
44-
* <a href="https://kotlinlang.org/docs/null-safety.html">Kotlin null safety</a> and {@code @Nullable} annotations
45-
* regardless of their package (from Spring, JSR-305 or Jakarta set of annotations for example).
44+
* <a href="https://kotlinlang.org/docs/null-safety.html">Kotlin null safety</a>, {@code @Nullable} annotations
45+
* regardless of their package (from Spring, JSR-305 or Jakarta set of annotations for example) and Java primitive
46+
* types.
4647
*
4748
* @author Sebastien Deleuze
4849
* @since 7.0
4950
*/
5051
public enum Nullness {
5152

5253
/**
53-
* Unspecified nullness (Java and JSpecify {@code @NullUnmarked} defaults).
54+
* Unspecified nullness (Java default for non-primitive types and JSpecify {@code @NullUnmarked} code).
5455
*/
5556
UNSPECIFIED,
5657

@@ -60,7 +61,7 @@ public enum Nullness {
6061
NULLABLE,
6162

6263
/**
63-
* Will not include null (Kotlin and JSpecify {@code @NullMarked} defaults).
64+
* Will not include null (Kotlin default and JSpecify {@code @NullMarked} code).
6465
*/
6566
NON_NULL;
6667

@@ -130,6 +131,9 @@ private static boolean hasNullableAnnotation(AnnotatedElement element) {
130131
}
131132

132133
private static Nullness jSpecifyNullness(AnnotatedElement annotatedElement, Class<?> declaringClass, AnnotatedType annotatedType) {
134+
if (annotatedType.getType() instanceof Class<?> clazz && clazz.isPrimitive()) {
135+
return (clazz != void.class ? Nullness.NON_NULL : Nullness.UNSPECIFIED);
136+
}
133137
if (annotatedType.isAnnotationPresent(Nullable.class)) {
134138
return Nullness.NULLABLE;
135139
}

spring-core/src/test/java/org/springframework/core/NullnessTests.java

+16
Original file line numberDiff line numberDiff line change
@@ -377,4 +377,20 @@ void customNullableField() throws NoSuchFieldException {
377377
Assertions.assertThat(nullness).isEqualTo(Nullness.NULLABLE);
378378
}
379379

380+
// Primitive types
381+
382+
@Test
383+
void primitiveField() throws NoSuchFieldException {
384+
var field = NullnessFields.class.getDeclaredField("primitiveField");
385+
var nullness = Nullness.forField(field);
386+
Assertions.assertThat(nullness).isEqualTo(Nullness.NON_NULL);
387+
}
388+
389+
@Test
390+
void voidMethod() throws NoSuchMethodException {
391+
var method = JSpecifyProcessor.class.getMethod("voidProcess");
392+
var nullness = Nullness.forMethodReturnType(method);
393+
Assertions.assertThat(nullness).isEqualTo(Nullness.UNSPECIFIED);
394+
}
395+
380396
}

spring-core/src/testFixtures/java/org/springframework/core/testfixture/nullness/JSpecifyProcessor.java

+2
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,6 @@ public interface JSpecifyProcessor {
3636

3737
@NullMarked
3838
@NonNull String nonNullMarkedProcess();
39+
40+
void voidProcess();
3941
}

spring-core/src/testFixtures/java/org/springframework/core/testfixture/nullness/NullnessFields.java

+2
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,6 @@ public class NullnessFields {
2626

2727
@org.springframework.core.testfixture.nullness.custom.Nullable
2828
public String customNullableField;
29+
30+
public int primitiveField = 0;
2931
}

0 commit comments

Comments
 (0)