Skip to content

Commit 9d9383a

Browse files
committed
Specify generic type nullness in spring-core
Also in spring-core-test. See spring-projectsgh-34140
1 parent 435cb0c commit 9d9383a

31 files changed

+160
-134
lines changed

Diff for: spring-core-test/src/main/java/org/springframework/core/test/tools/CompileWithForkedClassLoaderClassLoader.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@ final class CompileWithForkedClassLoaderClassLoader extends ClassLoader {
3737

3838
private final ClassLoader testClassLoader;
3939

40-
private Function<String, byte[]> classResourceLookup = name -> null;
40+
private Function<String, byte @Nullable []> classResourceLookup = name -> null;
4141

4242

4343
public CompileWithForkedClassLoaderClassLoader(ClassLoader testClassLoader) {
@@ -48,7 +48,7 @@ public CompileWithForkedClassLoaderClassLoader(ClassLoader testClassLoader) {
4848

4949
// Invoked reflectively by DynamicClassLoader
5050
@SuppressWarnings("unused")
51-
void setClassResourceLookup(Function<String, byte[]> classResourceLookup) {
51+
void setClassResourceLookup(Function<String, byte @Nullable []> classResourceLookup) {
5252
this.classResourceLookup = classResourceLookup;
5353
}
5454

Diff for: spring-core-test/src/main/java/org/springframework/core/test/tools/DynamicClassLoader.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -71,7 +71,7 @@ public DynamicClassLoader(ClassLoader parent, ClassFiles classFiles, ResourceFil
7171
"setClassResourceLookup", Function.class);
7272
ReflectionUtils.makeAccessible(setClassResourceLookupMethod);
7373
ReflectionUtils.invokeMethod(setClassResourceLookupMethod,
74-
getParent(), (Function<String, byte[]>) this::findClassBytes);
74+
getParent(), (Function<String, byte @Nullable []>) this::findClassBytes);
7575
this.defineClassMethod = lookupMethod(parentClass,
7676
"defineDynamicClass", String.class, byte[].class, int.class, int.class);
7777
ReflectionUtils.makeAccessible(this.defineClassMethod);

Diff for: spring-core/src/main/java/org/springframework/aot/generate/MethodReference.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -106,7 +106,7 @@ static ArgumentCodeGenerator of(Class<?> argumentType, String argumentCode) {
106106
* @param function the resolver function
107107
* @return a new {@link ArgumentCodeGenerator} instance backed by the function
108108
*/
109-
static ArgumentCodeGenerator from(Function<TypeName, CodeBlock> function) {
109+
static ArgumentCodeGenerator from(Function<TypeName, @Nullable CodeBlock> function) {
110110
return function::apply;
111111
}
112112

Diff for: spring-core/src/main/java/org/springframework/core/MethodParameter.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ public void initParameterNameDiscovery(@Nullable ParameterNameDiscoverer paramet
706706
}
707707
ParameterNameDiscoverer discoverer = this.parameterNameDiscoverer;
708708
if (discoverer != null) {
709-
String[] parameterNames = null;
709+
@Nullable String[] parameterNames = null;
710710
if (this.executable instanceof Method method) {
711711
parameterNames = discoverer.getParameterNames(method);
712712
}
@@ -865,7 +865,7 @@ private static int validateIndex(Executable executable, int parameterIndex) {
865865
* @return the corresponding MethodParameter instance
866866
* @since 6.1
867867
*/
868-
public static MethodParameter forFieldAwareConstructor(Constructor<?> ctor, int parameterIndex, String fieldName) {
868+
public static MethodParameter forFieldAwareConstructor(Constructor<?> ctor, int parameterIndex, @Nullable String fieldName) {
869869
return new FieldAwareConstructorParameter(ctor, parameterIndex, fieldName);
870870
}
871871

@@ -877,7 +877,7 @@ private static class FieldAwareConstructorParameter extends MethodParameter {
877877

878878
private volatile Annotation @Nullable [] combinedAnnotations;
879879

880-
public FieldAwareConstructorParameter(Constructor<?> constructor, int parameterIndex, String fieldName) {
880+
public FieldAwareConstructorParameter(Constructor<?> constructor, int parameterIndex, @Nullable String fieldName) {
881881
super(constructor, parameterIndex);
882882
this.parameterName = fieldName;
883883
}

Diff for: spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,12 +19,15 @@
1919
import java.lang.reflect.Method;
2020
import java.util.ArrayList;
2121
import java.util.List;
22+
import java.util.Objects;
2223
import java.util.Optional;
2324
import java.util.concurrent.CompletableFuture;
2425
import java.util.concurrent.CompletionStage;
2526
import java.util.concurrent.Flow;
2627
import java.util.function.Function;
2728

29+
import io.smallrye.mutiny.Multi;
30+
import io.smallrye.mutiny.Uni;
2831
import org.jspecify.annotations.Nullable;
2932
import org.reactivestreams.FlowAdapters;
3033
import org.reactivestreams.Publisher;
@@ -380,13 +383,13 @@ void registerAdapters(ReactiveAdapterRegistry registry) {
380383
io.smallrye.mutiny.groups.MultiCreate.class, "publisher", Flow.Publisher.class);
381384
registry.registerReactiveType(uniDesc,
382385
uni -> FlowAdapters.toPublisher((Flow.Publisher<Object>)
383-
ReflectionUtils.invokeMethod(uniToPublisher, ((io.smallrye.mutiny.Uni<?>) uni).convert())),
384-
publisher -> ReflectionUtils.invokeMethod(uniPublisher, io.smallrye.mutiny.Uni.createFrom(),
385-
FlowAdapters.toFlowPublisher(publisher)));
386+
Objects.requireNonNull(ReflectionUtils.invokeMethod(uniToPublisher, ((Uni<?>) uni).convert()))),
387+
publisher -> Objects.requireNonNull(ReflectionUtils.invokeMethod(uniPublisher, Uni.createFrom(),
388+
FlowAdapters.toFlowPublisher(publisher))));
386389
registry.registerReactiveType(multiDesc,
387390
multi -> FlowAdapters.toPublisher((Flow.Publisher<Object>) multi),
388-
publisher -> ReflectionUtils.invokeMethod(multiPublisher, io.smallrye.mutiny.Multi.createFrom(),
389-
FlowAdapters.toFlowPublisher(publisher)));
391+
publisher -> Objects.requireNonNull(ReflectionUtils.invokeMethod(multiPublisher, Multi.createFrom(),
392+
FlowAdapters.toFlowPublisher(publisher))));
390393
}
391394
else {
392395
// Mutiny 1 based on Reactive Streams

Diff for: spring-core/src/main/java/org/springframework/core/ResolvableType.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -825,9 +825,9 @@ else if (this.type instanceof ParameterizedType parameterizedType) {
825825
* @see #getGenerics()
826826
* @see #resolve()
827827
*/
828-
public Class<?>[] resolveGenerics() {
828+
public @Nullable Class<?>[] resolveGenerics() {
829829
ResolvableType[] generics = getGenerics();
830-
Class<?>[] resolvedGenerics = new Class<?>[generics.length];
830+
@Nullable Class<?>[] resolvedGenerics = new Class<?>[generics.length];
831831
for (int i = 0; i < generics.length; i++) {
832832
resolvedGenerics[i] = generics[i].resolve();
833833
}

Diff for: spring-core/src/main/java/org/springframework/core/SerializableTypeWrapper.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -205,7 +205,7 @@ else if (Type[].class == method.getReturnType() && ObjectUtils.isEmpty(args)) {
205205
if (returnValue == null) {
206206
return null;
207207
}
208-
Type[] result = new Type[((Type[]) returnValue).length];
208+
@Nullable Type[] result = new Type[((Type[]) returnValue).length];
209209
for (int i = 0; i < result.length; i++) {
210210
result[i] = forTypeProvider(new MethodInvokeTypeProvider(this.provider, method, i));
211211
}

Diff for: spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -478,7 +478,7 @@ public static <A extends Annotation> Set<A> getMergedRepeatableAnnotations(
478478
* attributes from all annotations found, or {@code null} if not found
479479
* @see #getAllAnnotationAttributes(AnnotatedElement, String, boolean, boolean)
480480
*/
481-
public static @Nullable MultiValueMap<String, Object> getAllAnnotationAttributes(
481+
public static MultiValueMap<String, @Nullable Object> getAllAnnotationAttributes(
482482
AnnotatedElement element, String annotationName) {
483483

484484
return getAllAnnotationAttributes(element, annotationName, false, false);
@@ -502,7 +502,7 @@ public static <A extends Annotation> Set<A> getMergedRepeatableAnnotations(
502502
* @return a {@link MultiValueMap} keyed by attribute name, containing the annotation
503503
* attributes from all annotations found, or {@code null} if not found
504504
*/
505-
public static @Nullable MultiValueMap<String, Object> getAllAnnotationAttributes(AnnotatedElement element,
505+
public static MultiValueMap<String, @Nullable Object> getAllAnnotationAttributes(AnnotatedElement element,
506506
String annotationName, final boolean classValuesAsString, final boolean nestedAnnotationsAsMap) {
507507

508508
Adapt[] adaptations = Adapt.values(classValuesAsString, nestedAnnotationsAsMap);

Diff for: spring-core/src/main/java/org/springframework/core/annotation/AnnotationAttributes.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -45,7 +45,7 @@
4545
* @see AnnotatedElementUtils
4646
*/
4747
@SuppressWarnings("serial")
48-
public class AnnotationAttributes extends LinkedHashMap<String, Object> {
48+
public class AnnotationAttributes extends LinkedHashMap<String, @Nullable Object> {
4949

5050
private static final String UNKNOWN = "unknown";
5151

@@ -83,7 +83,7 @@ public AnnotationAttributes(int initialCapacity) {
8383
* @param map original source of annotation attribute <em>key-value</em> pairs
8484
* @see #fromMap(Map)
8585
*/
86-
public AnnotationAttributes(Map<String, Object> map) {
86+
public AnnotationAttributes(Map<String, @Nullable Object> map) {
8787
super(map);
8888
this.annotationType = null;
8989
this.displayName = UNKNOWN;
@@ -376,10 +376,10 @@ private <T> T getRequiredAttribute(String attributeName, Class<T> expectedType)
376376

377377
@Override
378378
public String toString() {
379-
Iterator<Map.Entry<String, Object>> entries = entrySet().iterator();
379+
Iterator<Map.Entry<String, @Nullable Object>> entries = entrySet().iterator();
380380
StringBuilder sb = new StringBuilder("{");
381381
while (entries.hasNext()) {
382-
Map.Entry<String, Object> entry = entries.next();
382+
Map.Entry<String, @Nullable Object> entry = entries.next();
383383
sb.append(entry.getKey());
384384
sb.append('=');
385385
sb.append(valueToString(entry.getValue()));
@@ -391,7 +391,7 @@ public String toString() {
391391
return sb.toString();
392392
}
393393

394-
private String valueToString(Object value) {
394+
private String valueToString(@Nullable Object value) {
395395
if (value == this) {
396396
return "(this Map)";
397397
}
@@ -410,7 +410,7 @@ private String valueToString(Object value) {
410410
* to the {@link #AnnotationAttributes(Map)} constructor.
411411
* @param map original source of annotation attribute <em>key-value</em> pairs
412412
*/
413-
public static @Nullable AnnotationAttributes fromMap(@Nullable Map<String, Object> map) {
413+
public static @Nullable AnnotationAttributes fromMap(@Nullable Map<String, @Nullable Object> map) {
414414
if (map == null) {
415415
return null;
416416
}

Diff for: spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMappings.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@
2727

2828
import org.jspecify.annotations.Nullable;
2929

30+
import org.springframework.lang.Contract;
3031
import org.springframework.util.ConcurrentReferenceHashMap;
3132

3233
/**
@@ -87,7 +88,7 @@ private void addAllMappings(Class<? extends Annotation> annotationType,
8788
}
8889

8990
private void addMetaAnnotationsToQueue(Deque<AnnotationTypeMapping> queue, AnnotationTypeMapping source) {
90-
Annotation[] metaAnnotations = AnnotationsScanner.getDeclaredAnnotations(source.getAnnotationType(), false);
91+
@Nullable Annotation[] metaAnnotations = AnnotationsScanner.getDeclaredAnnotations(source.getAnnotationType(), false);
9192
for (Annotation metaAnnotation : metaAnnotations) {
9293
if (!isMappable(source, metaAnnotation)) {
9394
continue;
@@ -127,6 +128,7 @@ private void addIfPossible(Deque<AnnotationTypeMapping> queue, @Nullable Annotat
127128
}
128129
}
129130

131+
@Contract("_, null -> false")
130132
private boolean isMappable(AnnotationTypeMapping source, @Nullable Annotation metaAnnotation) {
131133
return (metaAnnotation != null && !this.filter.matches(metaAnnotation) &&
132134
!AnnotationFilter.PLAIN.matches(source.getAnnotationType()) &&

Diff for: spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -773,7 +773,7 @@ public static void validateAnnotation(Annotation annotation) {
773773
* @see #getAnnotationAttributes(Annotation, boolean, boolean)
774774
* @see #getAnnotationAttributes(AnnotatedElement, Annotation, boolean, boolean)
775775
*/
776-
public static Map<String, Object> getAnnotationAttributes(Annotation annotation) {
776+
public static Map<String, @Nullable Object> getAnnotationAttributes(Annotation annotation) {
777777
return getAnnotationAttributes(null, annotation);
778778
}
779779

@@ -791,7 +791,7 @@ public static Map<String, Object> getAnnotationAttributes(Annotation annotation)
791791
* corresponding attribute values as values (never {@code null})
792792
* @see #getAnnotationAttributes(Annotation, boolean, boolean)
793793
*/
794-
public static Map<String, Object> getAnnotationAttributes(
794+
public static Map<String, @Nullable Object> getAnnotationAttributes(
795795
Annotation annotation, boolean classValuesAsString) {
796796

797797
return getAnnotationAttributes(annotation, classValuesAsString, false);

Diff for: spring-core/src/main/java/org/springframework/core/annotation/AnnotationsProcessor.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -54,7 +54,7 @@ interface AnnotationsProcessor<C, R> {
5454
* {@code null} elements)
5555
* @return a {@code non-null} result if no further processing is required
5656
*/
57-
@Nullable R doWithAnnotations(C context, int aggregateIndex, @Nullable Object source, Annotation[] annotations);
57+
@Nullable R doWithAnnotations(C context, int aggregateIndex, @Nullable Object source, @Nullable Annotation[] annotations);
5858

5959
/**
6060
* Get the final result to be returned. By default this method returns

0 commit comments

Comments
 (0)