35
35
import org .springframework .core .convert .TypeDescriptor ;
36
36
import org .springframework .lang .Nullable ;
37
37
import org .springframework .util .ClassUtils ;
38
+ import org .springframework .util .CollectionUtils ;
38
39
import org .springframework .util .NumberUtils ;
39
40
import org .springframework .util .ReflectionUtils ;
40
41
import org .springframework .util .StringUtils ;
@@ -139,13 +140,17 @@ public <T> T convertIfNecessary(@Nullable String propertyName, @Nullable Object
139
140
140
141
// Value not of required type?
141
142
if (editor != null || (requiredType != null && !ClassUtils .isAssignableValue (requiredType , convertedValue ))) {
142
- if (typeDescriptor != null && requiredType != null && Collection .class .isAssignableFrom (requiredType ) &&
143
- convertedValue instanceof String text ) {
143
+ if (typeDescriptor != null && requiredType != null && Collection .class .isAssignableFrom (requiredType )) {
144
144
TypeDescriptor elementTypeDesc = typeDescriptor .getElementTypeDescriptor ();
145
145
if (elementTypeDesc != null ) {
146
146
Class <?> elementType = elementTypeDesc .getType ();
147
- if (Class .class == elementType || Enum .class .isAssignableFrom (elementType )) {
148
- convertedValue = StringUtils .commaDelimitedListToStringArray (text );
147
+ if (convertedValue instanceof String text ) {
148
+ if (Class .class == elementType || Enum .class .isAssignableFrom (elementType )) {
149
+ convertedValue = StringUtils .commaDelimitedListToStringArray (text );
150
+ }
151
+ if (editor == null && String .class != elementType ) {
152
+ editor = findDefaultEditor (Array .newInstance (elementType , 0 ).getClass ());
153
+ }
149
154
}
150
155
}
151
156
}
@@ -166,11 +171,23 @@ public <T> T convertIfNecessary(@Nullable String propertyName, @Nullable Object
166
171
}
167
172
else if (requiredType .isArray ()) {
168
173
// Array required -> apply appropriate conversion of elements.
169
- if (convertedValue instanceof String text && Enum .class .isAssignableFrom (requiredType .getComponentType ())) {
174
+ if (convertedValue instanceof String text &&
175
+ Enum .class .isAssignableFrom (requiredType .getComponentType ())) {
170
176
convertedValue = StringUtils .commaDelimitedListToStringArray (text );
171
177
}
172
178
return (T ) convertToTypedArray (convertedValue , propertyName , requiredType .getComponentType ());
173
179
}
180
+ else if (convertedValue .getClass ().isArray ()) {
181
+ if (Array .getLength (convertedValue ) == 1 ) {
182
+ convertedValue = Array .get (convertedValue , 0 );
183
+ standardConversion = true ;
184
+ }
185
+ else if (Collection .class .isAssignableFrom (requiredType )) {
186
+ convertedValue = convertToTypedCollection (CollectionUtils .arrayToList (convertedValue ),
187
+ propertyName , requiredType , typeDescriptor );
188
+ standardConversion = true ;
189
+ }
190
+ }
174
191
else if (convertedValue instanceof Collection <?> coll ) {
175
192
// Convert elements to target type, if determined.
176
193
convertedValue = convertToTypedCollection (coll , propertyName , requiredType , typeDescriptor );
@@ -181,10 +198,6 @@ else if (convertedValue instanceof Map<?, ?> map) {
181
198
convertedValue = convertToTypedMap (map , propertyName , requiredType , typeDescriptor );
182
199
standardConversion = true ;
183
200
}
184
- if (convertedValue .getClass ().isArray () && Array .getLength (convertedValue ) == 1 ) {
185
- convertedValue = Array .get (convertedValue , 0 );
186
- standardConversion = true ;
187
- }
188
201
if (String .class == requiredType && ClassUtils .isPrimitiveOrWrapper (convertedValue .getClass ())) {
189
202
// We can stringify any primitive value...
190
203
return (T ) convertedValue .toString ();
@@ -501,12 +514,11 @@ private Collection<?> convertToTypedCollection(Collection<?> original, @Nullable
501
514
502
515
Collection <Object > convertedCopy ;
503
516
try {
504
- if (approximable ) {
517
+ if (approximable && requiredType . isInstance ( original ) ) {
505
518
convertedCopy = CollectionFactory .createApproximateCollection (original , original .size ());
506
519
}
507
520
else {
508
- convertedCopy = (Collection <Object >)
509
- ReflectionUtils .accessibleConstructor (requiredType ).newInstance ();
521
+ convertedCopy = CollectionFactory .createCollection (requiredType , original .size ());
510
522
}
511
523
}
512
524
catch (Throwable ex ) {
@@ -576,12 +588,11 @@ private Collection<?> convertToTypedCollection(Collection<?> original, @Nullable
576
588
577
589
Map <Object , Object > convertedCopy ;
578
590
try {
579
- if (approximable ) {
591
+ if (approximable && requiredType . isInstance ( original ) ) {
580
592
convertedCopy = CollectionFactory .createApproximateMap (original , original .size ());
581
593
}
582
594
else {
583
- convertedCopy = (Map <Object , Object >)
584
- ReflectionUtils .accessibleConstructor (requiredType ).newInstance ();
595
+ convertedCopy = CollectionFactory .createMap (requiredType , original .size ());
585
596
}
586
597
}
587
598
catch (Throwable ex ) {
0 commit comments