Nullability refinements on private and static methods

Based on IntelliJ IDEA 2017.3 introspection results.

Issue: SPR-15756
This commit is contained in:
Juergen Hoeller
2017-09-22 18:22:12 +02:00
parent 60f47f4489
commit 7ae59d0c2a
88 changed files with 319 additions and 300 deletions

View File

@@ -766,6 +766,7 @@ public class ResolvableType implements Serializable {
return (this.resolved != null ? this.resolved : fallback);
}
@Nullable
private Class<?> resolveClass() {
if (this.type == EmptyType.INSTANCE) {
return null;
@@ -1474,6 +1475,7 @@ public class ResolvableType implements Serializable {
}
@Override
@Nullable
public Type getOwnerType() {
return null;
}

View File

@@ -153,7 +153,6 @@ public class AnnotatedElementUtils {
* @see #getMetaAnnotationTypes(AnnotatedElement, String)
* @see #hasMetaAnnotationTypes
*/
@Nullable
public static Set<String> getMetaAnnotationTypes(AnnotatedElement element, Class<? extends Annotation> annotationType) {
Assert.notNull(element, "AnnotatedElement must not be null");
Assert.notNull(annotationType, "'annotationType' must not be null");
@@ -1114,7 +1113,7 @@ public class AnnotatedElementUtils {
processor.alwaysProcesses()) {
T result = processor.process(element, annotation, metaDepth);
if (result != null) {
if (processor.aggregates() && metaDepth == 0) {
if (aggregatedResults != null && metaDepth == 0) {
aggregatedResults.add(result);
}
else {
@@ -1126,7 +1125,7 @@ public class AnnotatedElementUtils {
else if (currentAnnotationType == containerType) {
for (Annotation contained : getRawAnnotationsFromContainer(element, annotation)) {
T result = processor.process(element, contained, metaDepth);
if (result != null) {
if (aggregatedResults != null && result != null) {
// No need to post-process since repeatable annotations within a
// container cannot be composed annotations.
aggregatedResults.add(result);
@@ -1144,7 +1143,7 @@ public class AnnotatedElementUtils {
containerType, processor, visited, metaDepth + 1);
if (result != null) {
processor.postProcess(currentAnnotationType, annotation, result);
if (processor.aggregates() && metaDepth == 0) {
if (aggregatedResults != null && metaDepth == 0) {
aggregatedResults.add(result);
}
else {
@@ -1154,7 +1153,7 @@ public class AnnotatedElementUtils {
}
}
if (processor.aggregates()) {
if (aggregatedResults != null) {
// Prepend to support top-down ordering within class hierarchies
processor.getAggregatedResults().addAll(0, aggregatedResults);
}
@@ -1237,9 +1236,10 @@ public class AnnotatedElementUtils {
return null;
}
private static <T> T searchOnInterfaces(Method method, Class<? extends Annotation> annotationType,
String annotationName, Class<? extends Annotation> containerType, Processor<T> processor,
Set<AnnotatedElement> visited, int metaDepth, Class<?>[] ifcs) {
@Nullable
private static <T> T searchOnInterfaces(Method method, @Nullable Class<? extends Annotation> annotationType,
@Nullable String annotationName, @Nullable Class<? extends Annotation> containerType,
Processor<T> processor, Set<AnnotatedElement> visited, int metaDepth, Class<?>[] ifcs) {
for (Class<?> iface : ifcs) {
if (AnnotationUtils.isInterfaceWithAnnotatedMethods(iface)) {
@@ -1495,7 +1495,6 @@ public class AnnotatedElementUtils {
static class AlwaysTrueBooleanAnnotationProcessor extends SimpleAnnotationProcessor<Boolean> {
@Override
@Nullable
public final Boolean process(@Nullable AnnotatedElement annotatedElement, Annotation annotation, int metaDepth) {
return Boolean.TRUE;
}

View File

@@ -292,7 +292,6 @@ public abstract class AnnotationUtils {
* @see java.lang.annotation.Repeatable
* @see java.lang.reflect.AnnotatedElement#getAnnotationsByType
*/
@Nullable
public static <A extends Annotation> Set<A> getRepeatableAnnotations(AnnotatedElement annotatedElement,
Class<A> annotationType) {
@@ -1524,7 +1523,6 @@ public abstract class AnnotationUtils {
* @see #synthesizeAnnotation(Map, Class, AnnotatedElement)
* @see #synthesizeAnnotation(Annotation, AnnotatedElement)
*/
@Nullable
public static <A extends Annotation> A synthesizeAnnotation(Class<A> annotationType) {
return synthesizeAnnotation(Collections.<String, Object> emptyMap(), annotationType, null);
}

View File

@@ -129,6 +129,7 @@ final class ObjectToObjectConverter implements ConditionalGenericConverter {
return (getValidatedMember(targetClass, sourceClass) != null);
}
@Nullable
private static Member getValidatedMember(Class<?> targetClass, Class<?> sourceClass) {
Member member = conversionMemberCache.get(targetClass);
if (isApplicable(member, sourceClass)) {
@@ -166,6 +167,7 @@ final class ObjectToObjectConverter implements ConditionalGenericConverter {
}
}
@Nullable
private static Method determineToMethod(Class<?> targetClass, Class<?> sourceClass) {
if (String.class == targetClass || String.class == sourceClass) {
// Do not accept a toString() method or any to methods on String itself
@@ -177,6 +179,7 @@ final class ObjectToObjectConverter implements ConditionalGenericConverter {
ClassUtils.isAssignable(targetClass, method.getReturnType()) ? method : null);
}
@Nullable
private static Method determineFactoryMethod(Class<?> targetClass, Class<?> sourceClass) {
if (String.class == targetClass) {
// Do not accept the String.valueOf(Object) method

View File

@@ -30,9 +30,8 @@ import javax.annotation.meta.TypeQualifierNickname;
* 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 parameter, return value, and field level.
* Methods overrides should repeat parent {@code @NonNull} annotations unless they behave
* differently.
* <p>Should be used at parameter, return value, and field level. Method 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

View File

@@ -27,8 +27,9 @@ 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.
* 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>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.

View File

@@ -21,15 +21,15 @@ 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.
* non-nullable by default for a given package.
*
* <p>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.

View File

@@ -30,9 +30,8 @@ import javax.annotation.meta.When;
* 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 parameter, return value, and field level.
* Methods overrides should repeat parent {@code @Nullable} annotations unless they behave
* differently.
* <p>Should be used at parameter, return value, and field level. Methods override should
* repeat parent {@code @Nullable} annotations unless they behave differently.
*
* <p>Can be used in association with {@code NonNullApi} or {@code @NonNullFields} to
* override the default non-nullable semantic to nullable.

View File

@@ -20,8 +20,6 @@ import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import org.springframework.lang.Nullable;
/**
* A simple utility class for Base64 encoding and decoding.
*
@@ -90,9 +88,8 @@ public abstract class Base64Utils {
* supported, i.e. neither Java 8 nor Apache Commons Codec is present at runtime
* @since 4.2.4
*/
@Nullable
public static byte[] decodeUrlSafe(@Nullable byte[] src) {
if (src == null || src.length == 0) {
public static byte[] decodeUrlSafe(byte[] src) {
if (src.length == 0) {
return src;
}
return Base64.getUrlDecoder().decode(src);
@@ -130,7 +127,6 @@ public abstract class Base64Utils {
* @throws IllegalStateException if Base64 encoding between byte arrays is not
* supported, i.e. neither Java 8 nor Apache Commons Codec is present at runtime
*/
@Nullable
public static String encodeToUrlSafeString(byte[] src) {
return new String(encodeUrlSafe(src), DEFAULT_CHARSET);
}
@@ -143,7 +139,6 @@ public abstract class Base64Utils {
* @throws IllegalStateException if Base64 encoding between byte arrays is not
* supported, i.e. neither Java 8 nor Apache Commons Codec is present at runtime
*/
@Nullable
public static byte[] decodeFromUrlSafeString(String src) {
return decodeUrlSafe(src.getBytes(DEFAULT_CHARSET));
}

View File

@@ -306,7 +306,6 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
public boolean remove(Object key, final Object value) {
Boolean result = doTask(key, new Task<Boolean>(TaskOption.RESTRUCTURE_AFTER, TaskOption.SKIP_IF_EMPTY) {
@Override
@Nullable
protected Boolean execute(@Nullable Reference<K, V> reference, @Nullable Entry<K, V> entry) {
if (entry != null && ObjectUtils.nullSafeEquals(entry.getValue(), value)) {
if (reference != null) {
@@ -324,7 +323,6 @@ public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
public boolean replace(K key, final V oldValue, final V newValue) {
Boolean result = doTask(key, new Task<Boolean>(TaskOption.RESTRUCTURE_BEFORE, TaskOption.SKIP_IF_EMPTY) {
@Override
@Nullable
protected Boolean execute(@Nullable Reference<K, V> reference, @Nullable Entry<K, V> entry) {
if (entry != null && ObjectUtils.nullSafeEquals(entry.getValue(), oldValue)) {
entry.setValue(newValue);

View File

@@ -396,12 +396,6 @@ public class FastByteArrayOutputStream extends OutputStream {
else if (len == 0) {
return 0;
}
else if (len < 0) {
throw new IllegalArgumentException("len must be 0 or greater: " + len);
}
else if (off < 0) {
throw new IllegalArgumentException("off must be 0 or greater: " + off);
}
else {
if (this.currentBuffer == null) {
// This stream doesn't have any data in it...

View File

@@ -51,7 +51,7 @@ public abstract class FutureAdapter<T, S> implements Future<T> {
* @param adaptee the future to delegate to
*/
protected FutureAdapter(Future<S> adaptee) {
Assert.notNull(adaptee, "'delegate' must not be null");
Assert.notNull(adaptee, "Delegate must not be null");
this.adaptee = adaptee;
}
@@ -98,6 +98,7 @@ public abstract class FutureAdapter<T, S> implements Future<T> {
case SUCCESS:
return (T) this.result;
case FAILURE:
Assert.state(this.result instanceof ExecutionException, "Failure without exception");
throw (ExecutionException) this.result;
case NEW:
try {

View File

@@ -165,6 +165,7 @@ public class XmlValidationModeDetector {
* Consume the next comment token, update the "inComment" flag
* and return the remaining content.
*/
@Nullable
private String consume(String line) {
int index = (this.inComment ? endComment(line) : startComment(line));
return (index == -1 ? null : line.substring(index));