Skip to content

Commit ca4de8f

Browse files
committed
Consistent simple value type check
Includes UUID treatment for data binding and bean dependency checks. Closes gh-30664
1 parent 858ea1a commit ca4de8f

File tree

4 files changed

+49
-47
lines changed

4 files changed

+49
-47
lines changed

spring-beans/src/main/java/org/springframework/beans/BeanUtils.java

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,10 @@
2323
import java.lang.reflect.InvocationTargetException;
2424
import java.lang.reflect.Method;
2525
import java.lang.reflect.Modifier;
26-
import java.net.URI;
27-
import java.net.URL;
28-
import java.time.temporal.Temporal;
2926
import java.util.Arrays;
3027
import java.util.Collections;
31-
import java.util.Date;
3228
import java.util.HashSet;
3329
import java.util.List;
34-
import java.util.Locale;
3530
import java.util.Map;
3631
import java.util.Set;
3732

@@ -663,26 +658,20 @@ public static boolean isSimpleProperty(Class<?> type) {
663658
}
664659

665660
/**
666-
* Check if the given type represents a "simple" value type: a primitive or
667-
* primitive wrapper, an enum, a String or other CharSequence, a Number, a
668-
* Date, a Temporal, a URI, a URL, a Locale, or a Class.
661+
* Check if the given type represents a "simple" value type for
662+
* bean property and data binding purposes:
663+
* a primitive or primitive wrapper, an {@code Enum}, a {@code String}
664+
* or other {@code CharSequence}, a {@code Number}, a {@code Date},
665+
* a {@code Temporal}, a {@code UUID}, a {@code URI}, a {@code URL},
666+
* a {@code Locale}, or a {@code Class}.
669667
* <p>{@code Void} and {@code void} are not considered simple value types.
670668
* @param type the type to check
671669
* @return whether the given type represents a "simple" value type
672670
* @see #isSimpleProperty(Class)
671+
* @see ClassUtils#isSimpleValueType(Class)
673672
*/
674673
public static boolean isSimpleValueType(Class<?> type) {
675-
return (Void.class != type && void.class != type &&
676-
(ClassUtils.isPrimitiveOrWrapper(type) ||
677-
Enum.class.isAssignableFrom(type) ||
678-
CharSequence.class.isAssignableFrom(type) ||
679-
Number.class.isAssignableFrom(type) ||
680-
Date.class.isAssignableFrom(type) ||
681-
Temporal.class.isAssignableFrom(type) ||
682-
URI.class == type ||
683-
URL.class == type ||
684-
Locale.class == type ||
685-
Class.class == type));
674+
return ClassUtils.isSimpleValueType(type);
686675
}
687676

688677

spring-beans/src/test/java/org/springframework/beans/BeanUtilsTests.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import java.util.Date;
3232
import java.util.List;
3333
import java.util.Locale;
34+
import java.util.UUID;
3435

3536
import org.junit.jupiter.api.Test;
3637
import org.junit.jupiter.params.ParameterizedTest;
@@ -470,7 +471,8 @@ void spr6063() {
470471
@ValueSource(classes = {
471472
boolean.class, char.class, byte.class, short.class, int.class, long.class, float.class, double.class,
472473
Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class,
473-
DayOfWeek.class, String.class, LocalDateTime.class, Date.class, URI.class, URL.class, Locale.class, Class.class
474+
DayOfWeek.class, String.class, LocalDateTime.class, Date.class, UUID.class, URI.class, URL.class,
475+
Locale.class, Class.class
474476
})
475477
void isSimpleValueType(Class<?> type) {
476478
assertThat(BeanUtils.isSimpleValueType(type)).as("Type [" + type.getName() + "] should be a simple value type").isTrue();
@@ -486,8 +488,8 @@ void isNotSimpleValueType(Class<?> type) {
486488
@ValueSource(classes = {
487489
boolean.class, char.class, byte.class, short.class, int.class, long.class, float.class, double.class,
488490
Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class,
489-
DayOfWeek.class, String.class, LocalDateTime.class, Date.class, URI.class, URL.class, Locale.class, Class.class,
490-
boolean[].class, Boolean[].class, LocalDateTime[].class, Date[].class
491+
DayOfWeek.class, String.class, LocalDateTime.class, Date.class, UUID.class, URI.class, URL.class,
492+
Locale.class, Class.class, boolean[].class, Boolean[].class, LocalDateTime[].class, Date[].class
491493
})
492494
void isSimpleProperty(Class<?> type) {
493495
assertThat(BeanUtils.isSimpleProperty(type)).as("Type [" + type.getName() + "] should be a simple property").isTrue();

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,26 @@
2424
import java.lang.reflect.Method;
2525
import java.lang.reflect.Modifier;
2626
import java.lang.reflect.Proxy;
27+
import java.net.URI;
28+
import java.net.URL;
29+
import java.time.temporal.Temporal;
2730
import java.util.Arrays;
2831
import java.util.Collection;
2932
import java.util.Collections;
33+
import java.util.Date;
3034
import java.util.Enumeration;
3135
import java.util.HashMap;
3236
import java.util.HashSet;
3337
import java.util.IdentityHashMap;
3438
import java.util.Iterator;
3539
import java.util.LinkedHashSet;
3640
import java.util.List;
41+
import java.util.Locale;
3742
import java.util.Map;
3843
import java.util.Optional;
3944
import java.util.Set;
4045
import java.util.StringJoiner;
46+
import java.util.UUID;
4147

4248
import org.springframework.lang.Nullable;
4349

@@ -528,6 +534,34 @@ public static Class<?> resolvePrimitiveIfNecessary(Class<?> clazz) {
528534
return (clazz.isPrimitive() && clazz != void.class ? primitiveTypeToWrapperMap.get(clazz) : clazz);
529535
}
530536

537+
/**
538+
* Delegate for {@link org.springframework.beans.BeanUtils#isSimpleValueType}.
539+
* Also used by {@link ObjectUtils#nullSafeConciseToString}.
540+
* <p>Check if the given type represents a common "simple" value type:
541+
* a primitive or primitive wrapper, an {@code Enum}, a {@code String}
542+
* or other {@code CharSequence}, a {@code Number}, a {@code Date},
543+
* a {@code Temporal}, a {@code UUID}, a {@code URI}, a {@code URL},
544+
* a {@code Locale}, or a {@code Class}.
545+
* <p>{@code Void} and {@code void} are not considered simple value types.
546+
* @param type the type to check
547+
* @return whether the given type represents a "simple" value type
548+
* @since 6.1
549+
*/
550+
public static boolean isSimpleValueType(Class<?> type) {
551+
return (Void.class != type && void.class != type &&
552+
(isPrimitiveOrWrapper(type) ||
553+
Enum.class.isAssignableFrom(type) ||
554+
CharSequence.class.isAssignableFrom(type) ||
555+
Number.class.isAssignableFrom(type) ||
556+
Date.class.isAssignableFrom(type) ||
557+
Temporal.class.isAssignableFrom(type) ||
558+
UUID.class.isAssignableFrom(type) ||
559+
URI.class == type ||
560+
URL.class == type ||
561+
Locale.class == type ||
562+
Class.class == type));
563+
}
564+
531565
/**
532566
* Check if the right-hand side type may be assigned to the left-hand side
533567
* type, assuming setting by reflection. Considers primitive wrapper

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

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,11 @@
1717
package org.springframework.util;
1818

1919
import java.lang.reflect.Array;
20-
import java.net.URI;
21-
import java.net.URL;
22-
import java.time.temporal.Temporal;
2320
import java.util.Arrays;
2421
import java.util.Collection;
25-
import java.util.Date;
26-
import java.util.Locale;
2722
import java.util.Map;
2823
import java.util.Optional;
2924
import java.util.StringJoiner;
30-
import java.util.UUID;
3125

3226
import org.springframework.lang.Nullable;
3327

@@ -918,6 +912,7 @@ public static String nullSafeToString(@Nullable short[] array) {
918912
* @since 5.3.27
919913
* @see #nullSafeToString(Object)
920914
* @see StringUtils#truncate(CharSequence)
915+
* @see ClassUtils#isSimpleValueType(Class)
921916
*/
922917
public static String nullSafeConciseToString(@Nullable Object obj) {
923918
if (obj == null) {
@@ -930,7 +925,7 @@ public static String nullSafeConciseToString(@Nullable Object obj) {
930925
return StringUtils.truncate(charSequence);
931926
}
932927
Class<?> type = obj.getClass();
933-
if (isSimpleValueType(type)) {
928+
if (ClassUtils.isSimpleValueType(type)) {
934929
String str = obj.toString();
935930
if (str != null) {
936931
return StringUtils.truncate(str);
@@ -939,22 +934,4 @@ public static String nullSafeConciseToString(@Nullable Object obj) {
939934
return type.getTypeName() + "@" + getIdentityHexString(obj);
940935
}
941936

942-
/**
943-
* Derived from {@link org.springframework.beans.BeanUtils#isSimpleValueType}.
944-
*/
945-
private static boolean isSimpleValueType(Class<?> type) {
946-
return (Void.class != type && void.class != type &&
947-
(ClassUtils.isPrimitiveOrWrapper(type) ||
948-
Enum.class.isAssignableFrom(type) ||
949-
CharSequence.class.isAssignableFrom(type) ||
950-
Number.class.isAssignableFrom(type) ||
951-
Date.class.isAssignableFrom(type) ||
952-
Temporal.class.isAssignableFrom(type) ||
953-
UUID.class.isAssignableFrom(type) ||
954-
URI.class == type ||
955-
URL.class == type ||
956-
Locale.class == type ||
957-
Class.class == type));
958-
}
959-
960937
}

0 commit comments

Comments
 (0)