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 e9cbd60339..830b8d4e19 100644 --- a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java @@ -69,6 +69,9 @@ public abstract class ObjectUtils { 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]; + private static final String NON_EMPTY_ARRAY = ARRAY_START + "..." + ARRAY_END; + private static final String EMPTY_COLLECTION = "[]"; + private static final String NON_EMPTY_COLLECTION = "[...]"; /** @@ -967,6 +970,16 @@ public abstract class ObjectUtils { return (!optional.isPresent() ? "Optional.empty" : String.format("Optional[%s]", nullSafeConciseToString(optional.get()))); } + if (obj.getClass().isArray()) { + return (Array.getLength(obj) == 0 ? EMPTY_ARRAY : NON_EMPTY_ARRAY); + } + if (obj instanceof Collection) { + return (((Collection) obj).isEmpty() ? EMPTY_COLLECTION : NON_EMPTY_COLLECTION); + } + if (obj instanceof Map) { + // EMPTY_ARRAY and NON_EMPTY_ARRAY are also used for maps. + return (((Map) obj).isEmpty() ? EMPTY_ARRAY : NON_EMPTY_ARRAY); + } if (obj instanceof Class) { return ((Class) obj).getName(); } diff --git a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java index 30b444f99c..a4d3b8cee3 100644 --- a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java @@ -30,7 +30,6 @@ import java.nio.file.Paths; import java.sql.SQLException; import java.time.LocalDate; import java.time.ZoneId; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Currency; @@ -39,6 +38,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.TimeZone; @@ -1059,20 +1059,49 @@ class ObjectUtilsTests { } @Test - void nullSafeConciseToStringForArraysAndCollections() { - List list = Arrays.asList("a", "b", "c"); - assertThat(ObjectUtils.nullSafeConciseToString(new int[][] {{1, 2}, {3, 4}})).startsWith(prefix(int[][].class)); - assertThat(ObjectUtils.nullSafeConciseToString(list.toArray(new Object[0]))).startsWith(prefix(Object[].class)); - assertThat(ObjectUtils.nullSafeConciseToString(list.toArray(new String[0]))).startsWith(prefix(String[].class)); - assertThat(ObjectUtils.nullSafeConciseToString(new ArrayList<>(list))).startsWith(prefix(ArrayList.class)); - assertThat(ObjectUtils.nullSafeConciseToString(new HashSet<>(list))).startsWith(prefix(HashSet.class)); + void nullSafeConciseToStringForEmptyArrays() { + assertThat(ObjectUtils.nullSafeConciseToString(new char[] {})).isEqualTo("{}"); + assertThat(ObjectUtils.nullSafeConciseToString(new int[][] {})).isEqualTo("{}"); + assertThat(ObjectUtils.nullSafeConciseToString(new String[] {})).isEqualTo("{}"); + assertThat(ObjectUtils.nullSafeConciseToString(new Integer[][] {})).isEqualTo("{}"); } @Test - void nullSafeConciseToStringForMaps() { + void nullSafeConciseToStringForNonEmptyArrays() { + assertThat(ObjectUtils.nullSafeConciseToString(new char[] {'a'})).isEqualTo("{...}"); + assertThat(ObjectUtils.nullSafeConciseToString(new int[][] {{1}, {2}})).isEqualTo("{...}"); + assertThat(ObjectUtils.nullSafeConciseToString(new String[] {"enigma"})).isEqualTo("{...}"); + assertThat(ObjectUtils.nullSafeConciseToString(new Integer[][] {{1}, {2}})).isEqualTo("{...}"); + } + + @Test + void nullSafeConciseToStringForEmptyCollections() { + List list = Collections.emptyList(); + Set set = Collections.emptySet(); + assertThat(ObjectUtils.nullSafeConciseToString(list)).isEqualTo("[]"); + assertThat(ObjectUtils.nullSafeConciseToString(set)).isEqualTo("[]"); + } + + @Test + void nullSafeConciseToStringForNonEmptyCollections() { + List list = Arrays.asList("a", "b"); + Set set = new HashSet<>(); + set.add("foo"); + assertThat(ObjectUtils.nullSafeConciseToString(list)).isEqualTo("[...]"); + assertThat(ObjectUtils.nullSafeConciseToString(set)).isEqualTo("[...]"); + } + + @Test + void nullSafeConciseToStringForEmptyMaps() { + Map map = Collections.emptyMap(); + assertThat(ObjectUtils.nullSafeConciseToString(map)).isEqualTo("{}"); + } + + @Test + void nullSafeConciseToStringForNonEmptyMaps() { HashMap map = new HashMap<>(); map.put("foo", 42L); - assertThat(ObjectUtils.nullSafeConciseToString(map)).startsWith(prefix(map.getClass())); + assertThat(ObjectUtils.nullSafeConciseToString(map)).isEqualTo("{...}"); } @Test