Skip to content

Commit a3907a6

Browse files
committed
Support arrays, collections, & maps in ObjectUtils.nullSafeConciseToString()
Prior to this commit, there was no explicit support for arrays, collections, and maps in nullSafeConciseToString(). This lead to string representations such as the following, regardless of whether the array, collection, or map was empty. - char[]@1623b78d - java.util.ImmutableCollections$List12@74fe5c40 - java.util.ImmutableCollections$MapN@10e31a9a This commit introduces explicit support for arrays, collections, and maps in nullSafeConciseToString(), which results in the following empty/non-empty string representations. - array: {} / {...} - collection: [] / [...] - map: {} / {...} The reason a string representation of an array uses "{}" instead of "[]" (like in Arrays.toString(...)) is that ObjectUtils.nullSafeToString(<array>) already follows that convention, and the implementation of nullSafeConciseToString() aligns with that for the sake of consistency. Closes gh-30811
1 parent dd16e01 commit a3907a6

File tree

2 files changed

+52
-10
lines changed

2 files changed

+52
-10
lines changed

spring-core/src/main/java/org/springframework/util/ObjectUtils.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ public abstract class ObjectUtils {
6969
private static final String EMPTY_ARRAY = ARRAY_START + ARRAY_END;
7070
private static final String ARRAY_ELEMENT_SEPARATOR = ", ";
7171
private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
72+
private static final String NON_EMPTY_ARRAY = ARRAY_START + "..." + ARRAY_END;
73+
private static final String EMPTY_COLLECTION = "[]";
74+
private static final String NON_EMPTY_COLLECTION = "[...]";
7275

7376

7477
/**
@@ -967,6 +970,16 @@ public static String nullSafeConciseToString(@Nullable Object obj) {
967970
return (!optional.isPresent() ? "Optional.empty" :
968971
String.format("Optional[%s]", nullSafeConciseToString(optional.get())));
969972
}
973+
if (obj.getClass().isArray()) {
974+
return (Array.getLength(obj) == 0 ? EMPTY_ARRAY : NON_EMPTY_ARRAY);
975+
}
976+
if (obj instanceof Collection<?>) {
977+
return (((Collection<?>) obj).isEmpty() ? EMPTY_COLLECTION : NON_EMPTY_COLLECTION);
978+
}
979+
if (obj instanceof Map<?, ?>) {
980+
// EMPTY_ARRAY and NON_EMPTY_ARRAY are also used for maps.
981+
return (((Map<?, ?>) obj).isEmpty() ? EMPTY_ARRAY : NON_EMPTY_ARRAY);
982+
}
970983
if (obj instanceof Class<?>) {
971984
return ((Class<?>) obj).getName();
972985
}

spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import java.sql.SQLException;
3131
import java.time.LocalDate;
3232
import java.time.ZoneId;
33-
import java.util.ArrayList;
3433
import java.util.Arrays;
3534
import java.util.Collections;
3635
import java.util.Currency;
@@ -39,6 +38,7 @@
3938
import java.util.HashSet;
4039
import java.util.List;
4140
import java.util.Locale;
41+
import java.util.Map;
4242
import java.util.Optional;
4343
import java.util.Set;
4444
import java.util.TimeZone;
@@ -1059,20 +1059,49 @@ void nullSafeConciseToStringForZoneId() {
10591059
}
10601060

10611061
@Test
1062-
void nullSafeConciseToStringForArraysAndCollections() {
1063-
List<String> list = Arrays.asList("a", "b", "c");
1064-
assertThat(ObjectUtils.nullSafeConciseToString(new int[][] {{1, 2}, {3, 4}})).startsWith(prefix(int[][].class));
1065-
assertThat(ObjectUtils.nullSafeConciseToString(list.toArray(new Object[0]))).startsWith(prefix(Object[].class));
1066-
assertThat(ObjectUtils.nullSafeConciseToString(list.toArray(new String[0]))).startsWith(prefix(String[].class));
1067-
assertThat(ObjectUtils.nullSafeConciseToString(new ArrayList<>(list))).startsWith(prefix(ArrayList.class));
1068-
assertThat(ObjectUtils.nullSafeConciseToString(new HashSet<>(list))).startsWith(prefix(HashSet.class));
1062+
void nullSafeConciseToStringForEmptyArrays() {
1063+
assertThat(ObjectUtils.nullSafeConciseToString(new char[] {})).isEqualTo("{}");
1064+
assertThat(ObjectUtils.nullSafeConciseToString(new int[][] {})).isEqualTo("{}");
1065+
assertThat(ObjectUtils.nullSafeConciseToString(new String[] {})).isEqualTo("{}");
1066+
assertThat(ObjectUtils.nullSafeConciseToString(new Integer[][] {})).isEqualTo("{}");
10691067
}
10701068

10711069
@Test
1072-
void nullSafeConciseToStringForMaps() {
1070+
void nullSafeConciseToStringForNonEmptyArrays() {
1071+
assertThat(ObjectUtils.nullSafeConciseToString(new char[] {'a'})).isEqualTo("{...}");
1072+
assertThat(ObjectUtils.nullSafeConciseToString(new int[][] {{1}, {2}})).isEqualTo("{...}");
1073+
assertThat(ObjectUtils.nullSafeConciseToString(new String[] {"enigma"})).isEqualTo("{...}");
1074+
assertThat(ObjectUtils.nullSafeConciseToString(new Integer[][] {{1}, {2}})).isEqualTo("{...}");
1075+
}
1076+
1077+
@Test
1078+
void nullSafeConciseToStringForEmptyCollections() {
1079+
List<String> list = Collections.emptyList();
1080+
Set<Integer> set = Collections.emptySet();
1081+
assertThat(ObjectUtils.nullSafeConciseToString(list)).isEqualTo("[]");
1082+
assertThat(ObjectUtils.nullSafeConciseToString(set)).isEqualTo("[]");
1083+
}
1084+
1085+
@Test
1086+
void nullSafeConciseToStringForNonEmptyCollections() {
1087+
List<String> list = Arrays.asList("a", "b");
1088+
Set<String> set = new HashSet<>();
1089+
set.add("foo");
1090+
assertThat(ObjectUtils.nullSafeConciseToString(list)).isEqualTo("[...]");
1091+
assertThat(ObjectUtils.nullSafeConciseToString(set)).isEqualTo("[...]");
1092+
}
1093+
1094+
@Test
1095+
void nullSafeConciseToStringForEmptyMaps() {
1096+
Map<String, Object> map = Collections.emptyMap();
1097+
assertThat(ObjectUtils.nullSafeConciseToString(map)).isEqualTo("{}");
1098+
}
1099+
1100+
@Test
1101+
void nullSafeConciseToStringForNonEmptyMaps() {
10731102
HashMap<String, Object> map = new HashMap<>();
10741103
map.put("foo", 42L);
1075-
assertThat(ObjectUtils.nullSafeConciseToString(map)).startsWith(prefix(map.getClass()));
1104+
assertThat(ObjectUtils.nullSafeConciseToString(map)).isEqualTo("{...}");
10761105
}
10771106

10781107
@Test

0 commit comments

Comments
 (0)