diff --git a/spring-core/src/main/java/org/springframework/core/Nullness.java b/spring-core/src/main/java/org/springframework/core/Nullness.java index 09542c908b..e8d713fd7c 100644 --- a/spring-core/src/main/java/org/springframework/core/Nullness.java +++ b/spring-core/src/main/java/org/springframework/core/Nullness.java @@ -181,10 +181,10 @@ public enum Nullness { public static Nullness forMethodReturnType(Method method) { KFunction function = ReflectJvmMapping.getKotlinFunction(method); - if (function != null && function.getReturnType().isMarkedNullable()) { - return Nullness.NULLABLE; + if (function != null && ReflectJvmMapping.getJavaType(function.getReturnType()) != void.class) { + return (function.getReturnType().isMarkedNullable() ? Nullness.NULLABLE : Nullness.NON_NULL); } - return Nullness.NON_NULL; + return Nullness.UNSPECIFIED; } public static Nullness forParameter(Executable executable, int parameterIndex) { diff --git a/spring-core/src/test/java/org/springframework/core/NullnessTests.java b/spring-core/src/test/java/org/springframework/core/NullnessTests.java index 2921401dd8..1cd68ae909 100644 --- a/spring-core/src/test/java/org/springframework/core/NullnessTests.java +++ b/spring-core/src/test/java/org/springframework/core/NullnessTests.java @@ -377,6 +377,13 @@ public class NullnessTests { Assertions.assertThat(nullness).isEqualTo(Nullness.NULLABLE); } + @Test + void voidClassMethod() throws NoSuchMethodException { + var method = JSpecifyProcessor.class.getMethod("voidClassProcess"); + var nullness = Nullness.forMethodReturnType(method); + Assertions.assertThat(nullness).isEqualTo(Nullness.UNSPECIFIED); + } + // Primitive types @Test diff --git a/spring-core/src/test/kotlin/org/springframework/core/NullnessKotlinTests.kt b/spring-core/src/test/kotlin/org/springframework/core/NullnessKotlinTests.kt index 2c8d6b6e36..87e9c40539 100644 --- a/spring-core/src/test/kotlin/org/springframework/core/NullnessKotlinTests.kt +++ b/spring-core/src/test/kotlin/org/springframework/core/NullnessKotlinTests.kt @@ -37,6 +37,13 @@ class NullnessKotlinTests { Assertions.assertThat(nullness).isEqualTo(Nullness.NULLABLE) } + @Test + fun unitReturnType() { + val method = ::unit.javaMethod!! + val nullness = Nullness.forMethodReturnType(method) + Assertions.assertThat(nullness).isEqualTo(Nullness.UNSPECIFIED) + } + @Test fun nullableParameter() { val method = ::nullable.javaMethod!! @@ -78,4 +85,7 @@ class NullnessKotlinTests { @Suppress("unused_parameter") fun nonNull(nonNull: String): String = "foo" + fun unit() { + } + } \ No newline at end of file diff --git a/spring-core/src/testFixtures/java/org/springframework/core/testfixture/nullness/JSpecifyProcessor.java b/spring-core/src/testFixtures/java/org/springframework/core/testfixture/nullness/JSpecifyProcessor.java index 9eee0f44d5..af0116d09a 100644 --- a/spring-core/src/testFixtures/java/org/springframework/core/testfixture/nullness/JSpecifyProcessor.java +++ b/spring-core/src/testFixtures/java/org/springframework/core/testfixture/nullness/JSpecifyProcessor.java @@ -37,5 +37,9 @@ public interface JSpecifyProcessor { @NullMarked @NonNull String nonNullMarkedProcess(); + @NullMarked void voidProcess(); + + @NullMarked + void voidClassProcess(); }