From 28ce133e4bd85c1f2782ed1eaccc943ff2f74c92 Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 23 Jun 2022 10:38:23 +0800 Subject: [PATCH] fix converter --- .../cn/hutool/core/collection/CollUtil.java | 6 +- .../core/convert/AbstractConverter.java | 8 +- .../core/convert/CompositeConverter.java | 213 ++++++++++++++++ .../java/cn/hutool/core/convert/Convert.java | 4 +- .../cn/hutool/core/convert/Converter.java | 4 +- ...erRegistry.java => RegisterConverter.java} | 236 ++---------------- .../impl/AtomicReferenceConverter.java | 4 +- .../core/convert/impl/MapConverter.java | 12 +- .../core/convert/impl/ReferenceConverter.java | 4 +- ...yTest.java => CompositeConverterTest.java} | 12 +- .../cn/hutool/core/convert/ConvertTest.java | 16 +- .../core/convert/ConvertToArrayTest.java | 4 +- .../cn/hutool/json/convert/JSONConverter.java | 6 +- 13 files changed, 281 insertions(+), 248 deletions(-) create mode 100644 hutool-core/src/main/java/cn/hutool/core/convert/CompositeConverter.java rename hutool-core/src/main/java/cn/hutool/core/convert/{ConverterRegistry.java => RegisterConverter.java} (56%) mode change 100755 => 100644 rename hutool-core/src/test/java/cn/hutool/core/convert/{ConverterRegistryTest.java => CompositeConverterTest.java} (64%) diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java index e38d11733..555fc7533 100755 --- a/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java @@ -9,7 +9,7 @@ import cn.hutool.core.comparator.CompareUtil; import cn.hutool.core.comparator.PinyinComparator; import cn.hutool.core.comparator.PropertyComparator; import cn.hutool.core.convert.Convert; -import cn.hutool.core.convert.ConverterRegistry; +import cn.hutool.core.convert.CompositeConverter; import cn.hutool.core.exceptions.UtilException; import cn.hutool.core.lang.hash.Hash32; import cn.hutool.core.map.MapUtil; @@ -1785,9 +1785,9 @@ public class CollUtil { iter = ListUtil.of(value).iterator(); } - final ConverterRegistry convert = ConverterRegistry.getInstance(); + final CompositeConverter convert = CompositeConverter.getInstance(); while (iter.hasNext()) { - collection.add(convert.convert(elementType, iter.next())); + collection.add((T) convert.convert(elementType, iter.next())); } return collection; diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/AbstractConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/AbstractConverter.java index 39e80f59a..4547c3751 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/AbstractConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/AbstractConverter.java @@ -19,13 +19,15 @@ public abstract class AbstractConverter implements Converter, Serializable { private static final long serialVersionUID = 1L; @Override - public Object convert(Type targetType, final Object value) { - Assert.notNull(targetType); + public Object convert(final Type targetType, final Object value) { if (null == value) { return null; } + if (TypeUtil.isUnknown(targetType)) { + throw new ConvertException("Unsupported convert to unKnow type: {}", targetType); + } - Class targetClass = TypeUtil.getClass(targetType); + final Class targetClass = TypeUtil.getClass(targetType); Assert.notNull(targetClass, "Target type is not a class!"); // 尝试强转 diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/CompositeConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/CompositeConverter.java new file mode 100644 index 000000000..3d017a647 --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/convert/CompositeConverter.java @@ -0,0 +1,213 @@ +package cn.hutool.core.convert; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.convert.impl.ArrayConverter; +import cn.hutool.core.convert.impl.BeanConverter; +import cn.hutool.core.convert.impl.CollectionConverter; +import cn.hutool.core.convert.impl.EnumConverter; +import cn.hutool.core.convert.impl.MapConverter; +import cn.hutool.core.convert.impl.NumberConverter; +import cn.hutool.core.convert.impl.PrimitiveConverter; +import cn.hutool.core.reflect.TypeReference; +import cn.hutool.core.reflect.TypeUtil; +import cn.hutool.core.util.ObjUtil; + +import java.lang.reflect.Type; +import java.util.Collection; +import java.util.Map; + +/** + * 复合转换器,融合了所有支持类型和自定义类型的转换规则 + *

+ * 将各种类型Convert对象放入符合转换器,通过convert方法查找目标类型对应的转换器,将被转换对象转换之。 + *

+ *

+ * 在此类中,存放着默认转换器和自定义转换器,默认转换器是Hutool中预定义的一些转换器,自定义转换器存放用户自定的转换器。 + *

+ * + * @author Looly + */ +public class CompositeConverter extends RegisterConverter { + private static final long serialVersionUID = 1L; + + /** + * 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载 + */ + private static class SingletonHolder { + /** + * 静态初始化器,由JVM来保证线程安全 + */ + private static final CompositeConverter INSTANCE = new CompositeConverter(); + } + + /** + * 获得单例的 ConverterRegistry + * + * @return ConverterRegistry + */ + public static CompositeConverter getInstance() { + return SingletonHolder.INSTANCE; + } + + /** + * 构造 + */ + public CompositeConverter() { + super(); + } + + /** + * 转换值为指定类型 + * + * @param type 类型 + * @param value 值 + * @return 转换后的值,默认为{@code null} + * @throws ConvertException 转换器不存在 + */ + @Override + public Object convert(final Type type, final Object value) throws ConvertException { + return convert(type, value, null); + } + + /** + * 转换值为指定类型
+ * 自定义转换器优先 + * + * @param 转换的目标类型(转换器转换到的类型) + * @param type 类型 + * @param value 值 + * @param defaultValue 默认值 + * @return 转换后的值 + * @throws ConvertException 转换器不存在 + */ + @Override + public T convert(final Type type, final Object value, final T defaultValue) throws ConvertException { + return convert(type, value, defaultValue, true); + } + + /** + * 转换值为指定类型 + * + * @param 转换的目标类型(转换器转换到的类型) + * @param type 类型目标 + * @param value 被转换值 + * @param defaultValue 默认值 + * @param isCustomFirst 是否自定义转换器优先 + * @return 转换后的值 + * @throws ConvertException 转换器不存在 + */ + @SuppressWarnings("unchecked") + public T convert(Type type, final Object value, final T defaultValue, final boolean isCustomFirst) throws ConvertException { + if (TypeUtil.isUnknown(type) && null == defaultValue) { + // 对于用户不指定目标类型的情况,返回原值 + return (T) value; + } + if (ObjUtil.isNull(value)) { + return defaultValue; + } + if (TypeUtil.isUnknown(type)) { + if(null == defaultValue){ + throw new ConvertException("Unsupported convert to unKnow type: {}", type); + } + type = defaultValue.getClass(); + } + + if (type instanceof TypeReference) { + type = ((TypeReference) type).getType(); + } + + // 标准转换器 + final Converter converter = getConverter(type, isCustomFirst); + if (null != converter) { + return converter.convert(type, value, defaultValue); + } + + Class rowType = (Class) TypeUtil.getClass(type); + if (null == rowType) { + if (null != defaultValue) { + rowType = (Class) defaultValue.getClass(); + } else { + throw new ConvertException("Can not get class from type: {}", type); + } + } + + // 特殊类型转换,包括Collection、Map、强转、Array等 + final T result = convertSpecial(type, rowType, value, defaultValue); + if (null != result) { + return result; + } + + // 尝试转Bean + if (BeanUtil.isBean(rowType)) { + return (T) BeanConverter.INSTANCE.convert(type, value); + } + + // 无法转换 + throw new ConvertException("Can not convert from {}: [{}] to [{}]", value.getClass().getName(), value, type.getTypeName()); + } + + // ----------------------------------------------------------- Private method start + + /** + * 特殊类型转换
+ * 包括: + * + *
+	 * Collection
+	 * Map
+	 * 强转(无需转换)
+	 * 数组
+	 * 
+ * + * @param 转换的目标类型(转换器转换到的类型) + * @param type 类型 + * @param value 值 + * @param defaultValue 默认值 + * @return 转换后的值 + */ + @SuppressWarnings("unchecked") + private T convertSpecial(final Type type, final Class rowType, final Object value, final T defaultValue) { + if (null == rowType) { + return null; + } + + // 集合转换(含有泛型参数,不可以默认强转) + if (Collection.class.isAssignableFrom(rowType)) { + return (T) CollectionConverter.INSTANCE.convert(type, value, (Collection) defaultValue); + } + + // Map类型(含有泛型参数,不可以默认强转) + if (Map.class.isAssignableFrom(rowType)) { + return (T) MapConverter.INSTANCE.convert(type, value, (Map) defaultValue); + } + + // 默认强转 + if (rowType.isInstance(value)) { + return (T) value; + } + + // 原始类型转换 + if(rowType.isPrimitive()){ + return PrimitiveConverter.INSTANCE.convert(type, value, defaultValue); + } + + // 数字类型转换 + if(Number.class.isAssignableFrom(rowType)){ + return NumberConverter.INSTANCE.convert(type, value, defaultValue); + } + + // 枚举转换 + if (rowType.isEnum()) { + return EnumConverter.INSTANCE.convert(type, value, defaultValue); + } + + // 数组转换 + if (rowType.isArray()) { + return ArrayConverter.INSTANCE.convert(type, value, defaultValue); + } + + // 表示非需要特殊转换的对象 + return null; + } + // ----------------------------------------------------------- Private method end +} diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java b/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java index 4e650eae6..260b618a5 100755 --- a/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/Convert.java @@ -745,9 +745,9 @@ public class Convert { * @since 5.3.2 */ public static T convertWithCheck(final Type type, final Object value, final T defaultValue, final boolean quietly) { - final ConverterRegistry registry = ConverterRegistry.getInstance(); + final CompositeConverter compositeConverter = CompositeConverter.getInstance(); try { - return registry.convert(type, value, defaultValue); + return compositeConverter.convert(type, value, defaultValue); } catch (final Exception e) { if(quietly){ return defaultValue; diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/Converter.java b/hutool-core/src/main/java/cn/hutool/core/convert/Converter.java index dcd4d1cd3..36f04b58b 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/Converter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/Converter.java @@ -8,7 +8,7 @@ import java.lang.reflect.Type; * 类型转换接口函数,根据给定的值和目标类型,由用户自定义转换规则。 * * @author looly - * @since 5.8.0 + * @since 6.0.0 */ @FunctionalInterface public interface Converter { @@ -36,6 +36,6 @@ public interface Converter { */ @SuppressWarnings("unchecked") default T convert(final Type targetType, final Object value, final T defaultValue) { - return ObjUtil.defaultIfNull((T) convert(targetType, value), defaultValue); + return (T) ObjUtil.defaultIfNull(convert(targetType, value), defaultValue); } } diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java b/hutool-core/src/main/java/cn/hutool/core/convert/RegisterConverter.java old mode 100755 new mode 100644 similarity index 56% rename from hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java rename to hutool-core/src/main/java/cn/hutool/core/convert/RegisterConverter.java index c17acd639..8d9112eb9 --- a/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/RegisterConverter.java @@ -1,30 +1,22 @@ package cn.hutool.core.convert; -import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.convert.impl.ArrayConverter; import cn.hutool.core.convert.impl.AtomicBooleanConverter; import cn.hutool.core.convert.impl.AtomicIntegerArrayConverter; import cn.hutool.core.convert.impl.AtomicLongArrayConverter; import cn.hutool.core.convert.impl.AtomicReferenceConverter; -import cn.hutool.core.convert.impl.BeanConverter; import cn.hutool.core.convert.impl.BooleanConverter; import cn.hutool.core.convert.impl.CalendarConverter; import cn.hutool.core.convert.impl.CharacterConverter; import cn.hutool.core.convert.impl.CharsetConverter; import cn.hutool.core.convert.impl.ClassConverter; -import cn.hutool.core.convert.impl.CollectionConverter; import cn.hutool.core.convert.impl.CurrencyConverter; import cn.hutool.core.convert.impl.DateConverter; import cn.hutool.core.convert.impl.DurationConverter; -import cn.hutool.core.convert.impl.EnumConverter; import cn.hutool.core.convert.impl.LocaleConverter; -import cn.hutool.core.convert.impl.MapConverter; -import cn.hutool.core.convert.impl.NumberConverter; import cn.hutool.core.convert.impl.OptConverter; import cn.hutool.core.convert.impl.OptionalConverter; import cn.hutool.core.convert.impl.PathConverter; import cn.hutool.core.convert.impl.PeriodConverter; -import cn.hutool.core.convert.impl.PrimitiveConverter; import cn.hutool.core.convert.impl.ReferenceConverter; import cn.hutool.core.convert.impl.StackTraceElementConverter; import cn.hutool.core.convert.impl.StringConverter; @@ -36,9 +28,7 @@ import cn.hutool.core.convert.impl.UUIDConverter; import cn.hutool.core.date.DateTime; import cn.hutool.core.lang.Opt; import cn.hutool.core.reflect.ClassUtil; -import cn.hutool.core.reflect.TypeReference; import cn.hutool.core.reflect.TypeUtil; -import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ServiceLoaderUtil; import java.io.Serializable; @@ -60,7 +50,6 @@ import java.time.Period; import java.time.ZonedDateTime; import java.time.temporal.TemporalAccessor; import java.util.Calendar; -import java.util.Collection; import java.util.Currency; import java.util.Locale; import java.util.Map; @@ -74,18 +63,12 @@ import java.util.concurrent.atomic.AtomicLongArray; import java.util.concurrent.atomic.AtomicReference; /** - * 转换器登记中心 - *

- * 将各种类型Convert对象放入登记中心,通过convert方法查找目标类型对应的转换器,将被转换对象转换之。 - *

- *

- * 在此类中,存放着默认转换器和自定义转换器,默认转换器是Hutool中预定义的一些转换器,自定义转换器存放用户自定的转换器。 - *

+ * 基于类型注册的转换器,转换器默认提供一些固定的类型转换,用户可调用{@link #putCustom(Type, Converter)} 注册自定义转换规则 * - * @author Looly + * @author looly + * @since 6.0.0 */ -public class ConverterRegistry implements Serializable { - private static final long serialVersionUID = 1L; +public class RegisterConverter implements Converter, Serializable { /** * 默认类型转换器 @@ -96,50 +79,24 @@ public class ConverterRegistry implements Serializable { */ private volatile Map customConverterMap; - /** - * 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载 - */ - private static class SingletonHolder { - /** - * 静态初始化器,由JVM来保证线程安全 - */ - private static final ConverterRegistry INSTANCE = new ConverterRegistry(); - } - - /** - * 获得单例的 ConverterRegistry - * - * @return ConverterRegistry - */ - public static ConverterRegistry getInstance() { - return SingletonHolder.INSTANCE; - } - /** * 构造 */ - public ConverterRegistry() { + public RegisterConverter() { registerDefault(); registerCustomBySpi(); } - /** - * 登记自定义转换器 - * - * @param type 转换的目标类型 - * @param converter 转换器 - * @return ConverterRegistry - */ - public ConverterRegistry putCustom(final Type type, final Converter converter) { - if (null == customConverterMap) { - synchronized (this) { - if (null == customConverterMap) { - customConverterMap = new ConcurrentHashMap<>(); - } - } + @Override + public Object convert(final Type targetType, final Object value) throws ConvertException { + // 标准转换器 + final Converter converter = getConverter(targetType, true); + if (null != converter) { + return converter.convert(targetType, value); } - customConverterMap.put(type, converter); - return this; + + // 无法转换 + throw new ConvertException("Can not convert from {}: [{}] to [{}]", value.getClass().getName(), value, targetType.getTypeName()); } /** @@ -186,164 +143,28 @@ public class ConverterRegistry implements Serializable { } /** - * 转换值为指定类型 + * 登记自定义转换器 * - * @param 转换的目标类型(转换器转换到的类型) - * @param type 类型目标 - * @param value 被转换值 - * @param defaultValue 默认值 - * @param isCustomFirst 是否自定义转换器优先 - * @return 转换后的值 - * @throws ConvertException 转换器不存在 + * @param type 转换的目标类型 + * @param converter 转换器 + * @return ConverterRegistry */ - @SuppressWarnings("unchecked") - public T convert(Type type, final Object value, final T defaultValue, final boolean isCustomFirst) throws ConvertException { - if (TypeUtil.isUnknown(type) && null == defaultValue) { - // 对于用户不指定目标类型的情况,返回原值 - return (T) value; - } - if (ObjUtil.isNull(value)) { - return defaultValue; - } - if (TypeUtil.isUnknown(type)) { - if(null == defaultValue){ - throw new ConvertException("Unsupported convert to unknow type: {}", type); - } - type = defaultValue.getClass(); - } - - if (type instanceof TypeReference) { - type = ((TypeReference) type).getType(); - } - - // 标准转换器 - final Converter converter = getConverter(type, isCustomFirst); - if (null != converter) { - return converter.convert(type, value, defaultValue); - } - - Class rowType = (Class) TypeUtil.getClass(type); - if (null == rowType) { - if (null != defaultValue) { - rowType = (Class) defaultValue.getClass(); - } else { - throw new ConvertException("Can not get class from type: {}", type); + public RegisterConverter putCustom(final Type type, final Converter converter) { + if (null == customConverterMap) { + synchronized (this) { + if (null == customConverterMap) { + customConverterMap = new ConcurrentHashMap<>(); + } } } - - // 特殊类型转换,包括Collection、Map、强转、Array等 - final T result = convertSpecial(type, rowType, value, defaultValue); - if (null != result) { - return result; - } - - // 尝试转Bean - if (BeanUtil.isBean(rowType)) { - return (T) BeanConverter.INSTANCE.convert(type, value); - } - - // 无法转换 - throw new ConvertException("Can not convert from {}: [{}] to [{}]", value.getClass().getName(), value, type.getTypeName()); - } - - /** - * 转换值为指定类型
- * 自定义转换器优先 - * - * @param 转换的目标类型(转换器转换到的类型) - * @param type 类型 - * @param value 值 - * @param defaultValue 默认值 - * @return 转换后的值 - * @throws ConvertException 转换器不存在 - */ - public T convert(final Type type, final Object value, final T defaultValue) throws ConvertException { - return convert(type, value, defaultValue, true); - } - - /** - * 转换值为指定类型 - * - * @param 转换的目标类型(转换器转换到的类型) - * @param type 类型 - * @param value 值 - * @return 转换后的值,默认为{@code null} - * @throws ConvertException 转换器不存在 - */ - public T convert(final Type type, final Object value) throws ConvertException { - return convert(type, value, null); - } - - // ----------------------------------------------------------- Private method start - - /** - * 特殊类型转换
- * 包括: - * - *
-	 * Collection
-	 * Map
-	 * 强转(无需转换)
-	 * 数组
-	 * 
- * - * @param 转换的目标类型(转换器转换到的类型) - * @param type 类型 - * @param value 值 - * @param defaultValue 默认值 - * @return 转换后的值 - */ - @SuppressWarnings("unchecked") - private T convertSpecial(final Type type, final Class rowType, final Object value, final T defaultValue) { - if (null == rowType) { - return null; - } - - // 集合转换(含有泛型参数,不可以默认强转) - if (Collection.class.isAssignableFrom(rowType)) { - return (T) CollectionConverter.INSTANCE.convert(type, value, (Collection) defaultValue); - } - - // Map类型(含有泛型参数,不可以默认强转) - if (Map.class.isAssignableFrom(rowType)) { - return (T) MapConverter.INSTANCE.convert(type, value, (Map) defaultValue); - } - - // 默认强转 - if (rowType.isInstance(value)) { - return (T) value; - } - - // 原始类型转换 - if(rowType.isPrimitive()){ - return PrimitiveConverter.INSTANCE.convert(type, value, defaultValue); - } - - // 数字类型转换 - if(Number.class.isAssignableFrom(rowType)){ - return NumberConverter.INSTANCE.convert(type, value, defaultValue); - } - - // 枚举转换 - if (rowType.isEnum()) { - return EnumConverter.INSTANCE.convert(type, value, defaultValue); - } - - // 数组转换 - if (rowType.isArray()) { - return ArrayConverter.INSTANCE.convert(type, value, defaultValue); - } - - // 表示非需要特殊转换的对象 - return null; + customConverterMap.put(type, converter); + return this; } /** * 注册默认转换器 - * - * @return 转换器 */ - private ConverterRegistry registerDefault() { + private void registerDefault() { defaultConverterMap = new ConcurrentHashMap<>(); // 包装类转换器 @@ -397,8 +218,6 @@ public class ConverterRegistry implements Serializable { defaultConverterMap.put(StackTraceElement.class, new StackTraceElementConverter());// since 4.5.2 defaultConverterMap.put(Optional.class, new OptionalConverter());// since 5.0.0 defaultConverterMap.put(Opt.class, new OptConverter());// since 5.7.16 - - return this; } /** @@ -416,5 +235,4 @@ public class ConverterRegistry implements Serializable { } }); } - // ----------------------------------------------------------- Private method end } diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/AtomicReferenceConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/AtomicReferenceConverter.java index ac5d6ade3..e2174bbbe 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/impl/AtomicReferenceConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/AtomicReferenceConverter.java @@ -1,7 +1,7 @@ package cn.hutool.core.convert.impl; import cn.hutool.core.convert.AbstractConverter; -import cn.hutool.core.convert.ConverterRegistry; +import cn.hutool.core.convert.CompositeConverter; import cn.hutool.core.reflect.TypeUtil; import java.lang.reflect.Type; @@ -23,7 +23,7 @@ public class AtomicReferenceConverter extends AbstractConverter { Object targetValue = null; final Type paramType = TypeUtil.getTypeArgument(AtomicReference.class); if(false == TypeUtil.isUnknown(paramType)){ - targetValue = ConverterRegistry.getInstance().convert(paramType, value); + targetValue = CompositeConverter.getInstance().convert(paramType, value); } if(null == targetValue){ targetValue = value; diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/MapConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/MapConverter.java index d7aad7a2f..e1d733cdf 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/impl/MapConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/MapConverter.java @@ -2,7 +2,7 @@ package cn.hutool.core.convert.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.convert.ConvertException; -import cn.hutool.core.convert.ConverterRegistry; +import cn.hutool.core.convert.CompositeConverter; import cn.hutool.core.convert.Converter; import cn.hutool.core.map.MapUtil; import cn.hutool.core.reflect.TypeReference; @@ -26,7 +26,7 @@ public class MapConverter implements Converter, Serializable { public static MapConverter INSTANCE = new MapConverter(); @Override - public Object convert(Type targetType, Object value) throws ConvertException { + public Object convert(Type targetType, final Object value) throws ConvertException { if (targetType instanceof TypeReference) { targetType = ((TypeReference) targetType).getType(); } @@ -79,11 +79,11 @@ public class MapConverter implements Converter, Serializable { * @param targetMap 目标Map */ @SuppressWarnings({"rawtypes", "unchecked"}) - private void convertMapToMap(Type keyType, Type valueType, final Map srcMap, final Map targetMap) { - final ConverterRegistry convert = ConverterRegistry.getInstance(); + private void convertMapToMap(final Type keyType, final Type valueType, final Map srcMap, final Map targetMap) { + final CompositeConverter convert = CompositeConverter.getInstance(); srcMap.forEach((key, value) -> { - key = TypeUtil.isUnknown(keyType) ? key : convert.convert(keyType, key); - value = TypeUtil.isUnknown(valueType) ? value : convert.convert(valueType, value); + key = TypeUtil.isUnknown(keyType) ? key : convert.convert(keyType, key, null); + value = TypeUtil.isUnknown(valueType) ? value : convert.convert(valueType, value, null); targetMap.put(key, value); }); } diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/ReferenceConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/ReferenceConverter.java index 8899f5d5e..b31689d04 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/impl/ReferenceConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/ReferenceConverter.java @@ -1,7 +1,7 @@ package cn.hutool.core.convert.impl; import cn.hutool.core.convert.AbstractConverter; -import cn.hutool.core.convert.ConverterRegistry; +import cn.hutool.core.convert.CompositeConverter; import cn.hutool.core.text.StrUtil; import cn.hutool.core.reflect.TypeUtil; @@ -30,7 +30,7 @@ public class ReferenceConverter extends AbstractConverter { Object targetValue = null; final Type paramType = TypeUtil.getTypeArgument(targetClass); if(false == TypeUtil.isUnknown(paramType)){ - targetValue = ConverterRegistry.getInstance().convert(paramType, value); + targetValue = CompositeConverter.getInstance().convert(paramType, value); } if(null == targetValue){ targetValue = value; diff --git a/hutool-core/src/test/java/cn/hutool/core/convert/ConverterRegistryTest.java b/hutool-core/src/test/java/cn/hutool/core/convert/CompositeConverterTest.java similarity index 64% rename from hutool-core/src/test/java/cn/hutool/core/convert/ConverterRegistryTest.java rename to hutool-core/src/test/java/cn/hutool/core/convert/CompositeConverterTest.java index 63cdcf416..8cf80ae89 100644 --- a/hutool-core/src/test/java/cn/hutool/core/convert/ConverterRegistryTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/convert/CompositeConverterTest.java @@ -10,26 +10,26 @@ import java.lang.reflect.Type; * @author Looly * */ -public class ConverterRegistryTest { +public class CompositeConverterTest { @Test public void getConverterTest() { - final Converter converter = ConverterRegistry.getInstance().getConverter(CharSequence.class, false); + final Converter converter = CompositeConverter.getInstance().getConverter(CharSequence.class, false); Assert.assertNotNull(converter); } @Test public void customTest(){ final int a = 454553; - final ConverterRegistry converterRegistry = ConverterRegistry.getInstance(); + final CompositeConverter compositeConverter = CompositeConverter.getInstance(); - CharSequence result = converterRegistry.convert(CharSequence.class, a); + CharSequence result = (CharSequence) compositeConverter.convert(CharSequence.class, a); Assert.assertEquals("454553", result); //此处做为示例自定义CharSequence转换,因为Hutool中已经提供CharSequence转换,请尽量不要替换 //替换可能引发关联转换异常(例如覆盖CharSequence转换会影响全局) - converterRegistry.putCustom(CharSequence.class, new CustomConverter()); - result = converterRegistry.convert(CharSequence.class, a); + compositeConverter.putCustom(CharSequence.class, new CustomConverter()); + result = (CharSequence) compositeConverter.convert(CharSequence.class, a); Assert.assertEquals("Custom: 454553", result); } diff --git a/hutool-core/src/test/java/cn/hutool/core/convert/ConvertTest.java b/hutool-core/src/test/java/cn/hutool/core/convert/ConvertTest.java index c187d4dff..c6be5679a 100755 --- a/hutool-core/src/test/java/cn/hutool/core/convert/ConvertTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/convert/ConvertTest.java @@ -81,28 +81,28 @@ public class ConvertTest { final String a = " 34232"; final Integer aInteger = Convert.toInt(a); Assert.assertEquals(Integer.valueOf(34232), aInteger); - final int aInt = ConverterRegistry.getInstance().convert(int.class, a); + final int aInt = (int) CompositeConverter.getInstance().convert(int.class, a); Assert.assertEquals(34232, aInt); // 带小数测试 final String b = " 34232.00"; final Integer bInteger = Convert.toInt(b); Assert.assertEquals(Integer.valueOf(34232), bInteger); - final int bInt = ConverterRegistry.getInstance().convert(int.class, b); + final int bInt = (int) CompositeConverter.getInstance().convert(int.class, b); Assert.assertEquals(34232, bInt); // boolean测试 final boolean c = true; final Integer cInteger = Convert.toInt(c); Assert.assertEquals(Integer.valueOf(1), cInteger); - final int cInt = ConverterRegistry.getInstance().convert(int.class, c); + final int cInt = (int) CompositeConverter.getInstance().convert(int.class, c); Assert.assertEquals(1, cInt); // boolean测试 final String d = "08"; final Integer dInteger = Convert.toInt(d); Assert.assertEquals(Integer.valueOf(8), dInteger); - final int dInt = ConverterRegistry.getInstance().convert(int.class, d); + final int dInt = (int) CompositeConverter.getInstance().convert(int.class, d); Assert.assertEquals(8, dInt); } @@ -124,28 +124,28 @@ public class ConvertTest { final String a = " 342324545435435"; final Long aLong = Convert.toLong(a); Assert.assertEquals(Long.valueOf(342324545435435L), aLong); - final long aLong2 = ConverterRegistry.getInstance().convert(long.class, a); + final long aLong2 = (long) CompositeConverter.getInstance().convert(long.class, a); Assert.assertEquals(342324545435435L, aLong2); // 带小数测试 final String b = " 342324545435435.245435435"; final Long bLong = Convert.toLong(b); Assert.assertEquals(Long.valueOf(342324545435435L), bLong); - final long bLong2 = ConverterRegistry.getInstance().convert(long.class, b); + final long bLong2 = (long) CompositeConverter.getInstance().convert(long.class, b); Assert.assertEquals(342324545435435L, bLong2); // boolean测试 final boolean c = true; final Long cLong = Convert.toLong(c); Assert.assertEquals(Long.valueOf(1), cLong); - final long cLong2 = ConverterRegistry.getInstance().convert(long.class, c); + final long cLong2 = (long) CompositeConverter.getInstance().convert(long.class, c); Assert.assertEquals(1, cLong2); // boolean测试 final String d = "08"; final Long dLong = Convert.toLong(d); Assert.assertEquals(Long.valueOf(8), dLong); - final long dLong2 = ConverterRegistry.getInstance().convert(long.class, d); + final long dLong2 = (long) CompositeConverter.getInstance().convert(long.class, d); Assert.assertEquals(8, dLong2); } diff --git a/hutool-core/src/test/java/cn/hutool/core/convert/ConvertToArrayTest.java b/hutool-core/src/test/java/cn/hutool/core/convert/ConvertToArrayTest.java index 44fa3b833..af486b7ee 100644 --- a/hutool-core/src/test/java/cn/hutool/core/convert/ConvertToArrayTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/convert/ConvertToArrayTest.java @@ -79,11 +79,11 @@ public class ConvertToArrayTest { //数组转数组测试 final int[] a = new int[]{1,2,3,4}; - final long[] result = ConverterRegistry.getInstance().convert(long[].class, a); + final long[] result = (long[]) CompositeConverter.getInstance().convert(long[].class, a); Assert.assertArrayEquals(new long[]{1L, 2L, 3L, 4L}, result); //数组转数组测试 - final byte[] resultBytes = ConverterRegistry.getInstance().convert(byte[].class, a); + final byte[] resultBytes = (byte[]) CompositeConverter.getInstance().convert(byte[].class, a); Assert.assertArrayEquals(new byte[]{1, 2, 3, 4}, resultBytes); //字符串转数组 diff --git a/hutool-json/src/main/java/cn/hutool/json/convert/JSONConverter.java b/hutool-json/src/main/java/cn/hutool/json/convert/JSONConverter.java index ecac366a9..d42da472b 100644 --- a/hutool-json/src/main/java/cn/hutool/json/convert/JSONConverter.java +++ b/hutool-json/src/main/java/cn/hutool/json/convert/JSONConverter.java @@ -3,7 +3,7 @@ package cn.hutool.json.convert; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.convert.ConvertException; import cn.hutool.core.convert.Converter; -import cn.hutool.core.convert.ConverterRegistry; +import cn.hutool.core.convert.CompositeConverter; import cn.hutool.core.convert.impl.BeanConverter; import cn.hutool.core.convert.impl.DateConverter; import cn.hutool.core.convert.impl.TemporalAccessorConverter; @@ -34,10 +34,10 @@ public class JSONConverter implements Converter { public static JSONConverter INSTANCE = new JSONConverter(); - private static final ConverterRegistry registry; + private static final CompositeConverter registry; static { // 注册到转换中心 - registry = new ConverterRegistry(); + registry = new CompositeConverter(); registry.putCustom(JSON.class, INSTANCE); registry.putCustom(JSONObject.class, INSTANCE); registry.putCustom(JSONArray.class, INSTANCE);