From cca32a56a4e6a0495b200921cc32799cf8c3852b Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Sat, 20 Jul 2019 20:50:02 +0100 Subject: [PATCH] Use shared zero length array constants Update code that's often called so that zero length array results use a single shared static constant, rather than a new instance for each call. Closes gh-23340 --- .../core/annotation/AnnotationTypeMapping.java | 8 ++++++-- .../java/org/springframework/util/MethodInvoker.java | 7 +++++-- .../java/org/springframework/util/ObjectUtils.java | 5 +++-- .../java/org/springframework/util/StringUtils.java | 10 ++++++---- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMapping.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMapping.java index b8dc512c99..eebb9f6e3d 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMapping.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMapping.java @@ -48,6 +48,10 @@ import org.springframework.util.StringUtils; */ final class AnnotationTypeMapping { + + private static final MirrorSet[] EMPTY_MIRROR_SETS = new MirrorSet[0]; + + @Nullable private final AnnotationTypeMapping source; @@ -550,7 +554,7 @@ final class AnnotationTypeMapping { MirrorSets() { this.assigned = new MirrorSet[attributes.size()]; - this.mirrorSets = new MirrorSet[0]; + this.mirrorSets = EMPTY_MIRROR_SETS; } void updateFrom(Collection aliases) { @@ -575,7 +579,7 @@ final class AnnotationTypeMapping { mirrorSet.update(); Set unique = new LinkedHashSet<>(Arrays.asList(this.assigned)); unique.remove(null); - this.mirrorSets = unique.toArray(new MirrorSet[0]); + this.mirrorSets = unique.toArray(EMPTY_MIRROR_SETS); } } diff --git a/spring-core/src/main/java/org/springframework/util/MethodInvoker.java b/spring-core/src/main/java/org/springframework/util/MethodInvoker.java index 41d5742d9d..e7b78ec566 100644 --- a/spring-core/src/main/java/org/springframework/util/MethodInvoker.java +++ b/spring-core/src/main/java/org/springframework/util/MethodInvoker.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,6 +38,9 @@ import org.springframework.lang.Nullable; */ public class MethodInvoker { + private static final Object[] EMPTY_ARGUMENTS = new Object[0]; + + @Nullable protected Class targetClass; @@ -141,7 +144,7 @@ public class MethodInvoker { * Return the arguments for the method invocation. */ public Object[] getArguments() { - return (this.arguments != null ? this.arguments : new Object[0]); + return (this.arguments != null ? this.arguments : EMPTY_ARGUMENTS); } diff --git a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java index c3cbcb8d86..38ec08eacd 100644 --- a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java @@ -54,6 +54,7 @@ public abstract class ObjectUtils { private static final String ARRAY_END = "}"; private static final String EMPTY_ARRAY = ARRAY_START + ARRAY_END; private static final String ARRAY_ELEMENT_SEPARATOR = ", "; + private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; /** @@ -282,14 +283,14 @@ public abstract class ObjectUtils { return (Object[]) source; } if (source == null) { - return new Object[0]; + return EMPTY_OBJECT_ARRAY; } if (!source.getClass().isArray()) { throw new IllegalArgumentException("Source is not an array: " + source); } int length = Array.getLength(source); if (length == 0) { - return new Object[0]; + return EMPTY_OBJECT_ARRAY; } Class wrapperType = Array.get(source, 0).getClass(); Object[] newArray = (Object[]) Array.newInstance(wrapperType, length); diff --git a/spring-core/src/main/java/org/springframework/util/StringUtils.java b/spring-core/src/main/java/org/springframework/util/StringUtils.java index 7a9233ea48..9062fba981 100644 --- a/spring-core/src/main/java/org/springframework/util/StringUtils.java +++ b/spring-core/src/main/java/org/springframework/util/StringUtils.java @@ -60,6 +60,8 @@ import org.springframework.lang.Nullable; */ public abstract class StringUtils { + private static final String[] EMPTY_STRING_ARRAY = {}; + private static final String FOLDER_SEPARATOR = "/"; private static final String WINDOWS_FOLDER_SEPARATOR = "\\"; @@ -898,7 +900,7 @@ public abstract class StringUtils { * @return the resulting {@code String} array */ public static String[] toStringArray(@Nullable Collection collection) { - return (collection != null ? collection.toArray(new String[0]) : new String[0]); + return (collection != null || collection.isEmpty() ? collection.toArray(EMPTY_STRING_ARRAY) : EMPTY_STRING_ARRAY); } /** @@ -909,7 +911,7 @@ public abstract class StringUtils { * @return the resulting {@code String} array */ public static String[] toStringArray(@Nullable Enumeration enumeration) { - return (enumeration != null ? toStringArray(Collections.list(enumeration)) : new String[0]); + return (enumeration != null ? toStringArray(Collections.list(enumeration)) : EMPTY_STRING_ARRAY); } /** @@ -1151,7 +1153,7 @@ public abstract class StringUtils { @Nullable String str, String delimiters, boolean trimTokens, boolean ignoreEmptyTokens) { if (str == null) { - return new String[0]; + return EMPTY_STRING_ARRAY; } StringTokenizer st = new StringTokenizer(str, delimiters); @@ -1204,7 +1206,7 @@ public abstract class StringUtils { @Nullable String str, @Nullable String delimiter, @Nullable String charsToDelete) { if (str == null) { - return new String[0]; + return EMPTY_STRING_ARRAY; } if (delimiter == null) { return new String[] {str};