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 45da0adeaca..1f6a4b75e8d 100644 --- a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java @@ -59,7 +59,6 @@ public abstract class ObjectUtils { 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 = "[...]"; @@ -904,10 +903,9 @@ public abstract class ObjectUtils { *
  • {@code"Optional[]"} if {@code obj} is a non-empty {@code Optional}, * where {@code } is the result of invoking {@link #nullSafeConciseToString} * on the object contained in the {@code Optional}
  • - *
  • {@code "{}"} if {@code obj} is an empty array or {@link Map}
  • - *
  • {@code "{...}"} if {@code obj} is a non-empty array or {@link Map}
  • - *
  • {@code "[]"} if {@code obj} is an empty {@link Collection}
  • - *
  • {@code "[...]"} if {@code obj} is a non-empty {@link Collection}
  • + *
  • {@code "{}"} if {@code obj} is an empty array
  • + *
  • {@code "{...}"} if {@code obj} is a {@link Map} or a non-empty array
  • + *
  • {@code "[...]"} if {@code obj} is a {@link Collection}
  • *
  • {@linkplain Class#getName() Class name} if {@code obj} is a {@link Class}
  • *
  • {@linkplain Charset#name() Charset name} if {@code obj} is a {@link Charset}
  • *
  • {@linkplain TimeZone#getID() TimeZone ID} if {@code obj} is a {@link TimeZone}
  • @@ -946,12 +944,12 @@ public abstract class ObjectUtils { if (obj.getClass().isArray()) { return (Array.getLength(obj) == 0 ? EMPTY_ARRAY : NON_EMPTY_ARRAY); } - if (obj instanceof Collection collection) { - return (collection.isEmpty() ? EMPTY_COLLECTION : NON_EMPTY_COLLECTION); + if (obj instanceof Collection) { + return NON_EMPTY_COLLECTION; } - if (obj instanceof Map map) { - // EMPTY_ARRAY and NON_EMPTY_ARRAY are also used for maps. - return (map.isEmpty() ? EMPTY_ARRAY : NON_EMPTY_ARRAY); + if (obj instanceof Map) { + // NON_EMPTY_ARRAY is also used for maps. + return NON_EMPTY_ARRAY; } if (obj instanceof Class clazz) { return clazz.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 e67f964c3b9..8090c4be82f 100644 --- a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java @@ -1052,8 +1052,8 @@ class ObjectUtilsTests { void nullSafeConciseToStringForEmptyCollections() { List list = List.of(); Set set = Set.of(); - assertThat(ObjectUtils.nullSafeConciseToString(list)).isEqualTo("[]"); - assertThat(ObjectUtils.nullSafeConciseToString(set)).isEqualTo("[]"); + assertThat(ObjectUtils.nullSafeConciseToString(list)).isEqualTo("[...]"); + assertThat(ObjectUtils.nullSafeConciseToString(set)).isEqualTo("[...]"); } @Test @@ -1066,8 +1066,8 @@ class ObjectUtilsTests { @Test void nullSafeConciseToStringForEmptyMaps() { - Map map = new HashMap(); - assertThat(ObjectUtils.nullSafeConciseToString(map)).isEqualTo("{}"); + Map map = Map.of(); + assertThat(ObjectUtils.nullSafeConciseToString(map)).isEqualTo("{...}"); } @Test diff --git a/spring-expression/src/main/java/org/springframework/expression/TypeLocator.java b/spring-expression/src/main/java/org/springframework/expression/TypeLocator.java index ec1c531bb52..91ef19ed0c8 100644 --- a/spring-expression/src/main/java/org/springframework/expression/TypeLocator.java +++ b/spring-expression/src/main/java/org/springframework/expression/TypeLocator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2023 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. @@ -18,8 +18,9 @@ package org.springframework.expression; /** * Implementers of this interface are expected to be able to locate types. - * They may use a custom {@link ClassLoader} and/or deal with common - * package prefixes (e.g. {@code java.lang}) however they wish. + * + *

    They may use a custom {@link ClassLoader} and/or deal with common package + * prefixes (for example, {@code java.lang}) however they wish. * *

    See {@link org.springframework.expression.spel.support.StandardTypeLocator} * for an example implementation. @@ -31,8 +32,9 @@ package org.springframework.expression; public interface TypeLocator { /** - * Find a type by name. The name may or may not be fully qualified - * (e.g. {@code String} or {@code java.lang.String}). + * Find a type by name. + *

    The name may or may not be fully qualified — for example, + * {@code String} or {@code java.lang.String}. * @param typeName the type to be located * @return the {@code Class} object representing that type * @throws EvaluationException if there is a problem finding the type diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeLocator.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeLocator.java index dafb615271e..aa6ada780b0 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeLocator.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeLocator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2023 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. @@ -28,12 +28,16 @@ import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; /** - * A simple implementation of {@link TypeLocator} that uses the context ClassLoader - * (or any ClassLoader set upon it). It supports 'well-known' packages: So if a - * type cannot be found, it will try the registered imports to locate it. + * A simple implementation of {@link TypeLocator} that uses the default + * {@link ClassLoader} or a supplied {@link ClassLoader} to locate types. + * + *

    Supports well-known packages, registered as + * {@linkplain #registerImport(String) import prefixes}. If a type cannot be found, + * this class will attempt to locate it using the registered import prefixes. * * @author Andy Clement * @author Juergen Hoeller + * @author Sam Brannen * @since 3.0 */ public class StandardTypeLocator implements TypeLocator { @@ -41,20 +45,21 @@ public class StandardTypeLocator implements TypeLocator { @Nullable private final ClassLoader classLoader; - private final List knownPackagePrefixes = new ArrayList<>(1); + private final List importPrefixes = new ArrayList<>(1); /** - * Create a StandardTypeLocator for the default ClassLoader - * (typically, the thread context ClassLoader). + * Create a {@code StandardTypeLocator} for the default {@link ClassLoader} + * (typically, the thread context {@code ClassLoader}). + * @see ClassUtils#getDefaultClassLoader() */ public StandardTypeLocator() { this(ClassUtils.getDefaultClassLoader()); } /** - * Create a StandardTypeLocator for the given ClassLoader. - * @param classLoader the ClassLoader to delegate to + * Create a {@code StandardTypeLocator} for the given {@link ClassLoader}. + * @param classLoader the {@code ClassLoader} to delegate to */ public StandardTypeLocator(@Nullable ClassLoader classLoader) { this.classLoader = classLoader; @@ -65,49 +70,48 @@ public class StandardTypeLocator implements TypeLocator { /** * Register a new import prefix that will be used when searching for unqualified types. - * Expected format is something like "java.lang". - * @param prefix the prefix to register + *

    Expected format is something like {@code "java.lang"}. + * @param prefix the import prefix to register */ public void registerImport(String prefix) { - this.knownPackagePrefixes.add(prefix); + this.importPrefixes.add(prefix); } /** - * Remove that specified prefix from this locator's list of imports. - * @param prefix the prefix to remove + * Remove the specified prefix from this locator's list of imports. + * @param prefix the import prefix to remove */ public void removeImport(String prefix) { - this.knownPackagePrefixes.remove(prefix); + this.importPrefixes.remove(prefix); } /** - * Return a list of all the import prefixes registered with this StandardTypeLocator. - * @return a list of registered import prefixes + * Get the list of import prefixes registered with this {@code StandardTypeLocator}. + * @return the list of registered import prefixes */ public List getImportPrefixes() { - return Collections.unmodifiableList(this.knownPackagePrefixes); + return Collections.unmodifiableList(this.importPrefixes); } /** - * Find a (possibly unqualified) type reference - first using the type name as-is, - * then trying any registered prefixes if the type name cannot be found. + * Find a (possibly unqualified) type reference, first using the type name as-is, + * and then trying any registered import prefixes if the type name cannot be found. * @param typeName the type to locate * @return the class object for the type * @throws EvaluationException if the type cannot be found */ @Override public Class findType(String typeName) throws EvaluationException { - String nameToLookup = typeName; try { - return ClassUtils.forName(nameToLookup, this.classLoader); + return ClassUtils.forName(typeName, this.classLoader); } - catch (ClassNotFoundException ey) { + catch (ClassNotFoundException ex) { // try any registered prefixes before giving up } - for (String prefix : this.knownPackagePrefixes) { + for (String prefix : this.importPrefixes) { try { - nameToLookup = prefix + '.' + typeName; + String nameToLookup = prefix + '.' + typeName; return ClassUtils.forName(nameToLookup, this.classLoader); } catch (ClassNotFoundException ex) {