fix converter

This commit is contained in:
Looly 2022-06-23 10:38:23 +08:00
parent 245c76f4c7
commit 28ce133e4b
13 changed files with 281 additions and 248 deletions

View File

@ -9,7 +9,7 @@ import cn.hutool.core.comparator.CompareUtil;
import cn.hutool.core.comparator.PinyinComparator; import cn.hutool.core.comparator.PinyinComparator;
import cn.hutool.core.comparator.PropertyComparator; import cn.hutool.core.comparator.PropertyComparator;
import cn.hutool.core.convert.Convert; 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.exceptions.UtilException;
import cn.hutool.core.lang.hash.Hash32; import cn.hutool.core.lang.hash.Hash32;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
@ -1785,9 +1785,9 @@ public class CollUtil {
iter = ListUtil.of(value).iterator(); iter = ListUtil.of(value).iterator();
} }
final ConverterRegistry convert = ConverterRegistry.getInstance(); final CompositeConverter convert = CompositeConverter.getInstance();
while (iter.hasNext()) { while (iter.hasNext()) {
collection.add(convert.convert(elementType, iter.next())); collection.add((T) convert.convert(elementType, iter.next()));
} }
return collection; return collection;

View File

@ -19,13 +19,15 @@ public abstract class AbstractConverter implements Converter, Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Override @Override
public Object convert(Type targetType, final Object value) { public Object convert(final Type targetType, final Object value) {
Assert.notNull(targetType);
if (null == value) { if (null == value) {
return null; 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!"); Assert.notNull(targetClass, "Target type is not a class!");
// 尝试强转 // 尝试强转

View File

@ -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;
/**
* 复合转换器融合了所有支持类型和自定义类型的转换规则
* <p>
* 将各种类型Convert对象放入符合转换器通过convert方法查找目标类型对应的转换器将被转换对象转换之
* </p>
* <p>
* 在此类中存放着默认转换器和自定义转换器默认转换器是Hutool中预定义的一些转换器自定义转换器存放用户自定的转换器
* </p>
*
* @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);
}
/**
* 转换值为指定类型<br>
* 自定义转换器优先
*
* @param <T> 转换的目标类型转换器转换到的类型
* @param type 类型
* @param value
* @param defaultValue 默认值
* @return 转换后的值
* @throws ConvertException 转换器不存在
*/
@Override
public <T> T convert(final Type type, final Object value, final T defaultValue) throws ConvertException {
return convert(type, value, defaultValue, true);
}
/**
* 转换值为指定类型
*
* @param <T> 转换的目标类型转换器转换到的类型
* @param type 类型目标
* @param value 被转换值
* @param defaultValue 默认值
* @param isCustomFirst 是否自定义转换器优先
* @return 转换后的值
* @throws ConvertException 转换器不存在
*/
@SuppressWarnings("unchecked")
public <T> 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<T> rowType = (Class<T>) TypeUtil.getClass(type);
if (null == rowType) {
if (null != defaultValue) {
rowType = (Class<T>) defaultValue.getClass();
} else {
throw new ConvertException("Can not get class from type: {}", type);
}
}
// 特殊类型转换包括CollectionMap强转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
/**
* 特殊类型转换<br>
* 包括
*
* <pre>
* Collection
* Map
* 强转无需转换
* 数组
* </pre>
*
* @param <T> 转换的目标类型转换器转换到的类型
* @param type 类型
* @param value
* @param defaultValue 默认值
* @return 转换后的值
*/
@SuppressWarnings("unchecked")
private <T> T convertSpecial(final Type type, final Class<T> 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
}

View File

@ -745,9 +745,9 @@ public class Convert {
* @since 5.3.2 * @since 5.3.2
*/ */
public static <T> T convertWithCheck(final Type type, final Object value, final T defaultValue, final boolean quietly) { public static <T> 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 { try {
return registry.convert(type, value, defaultValue); return compositeConverter.convert(type, value, defaultValue);
} catch (final Exception e) { } catch (final Exception e) {
if(quietly){ if(quietly){
return defaultValue; return defaultValue;

View File

@ -8,7 +8,7 @@ import java.lang.reflect.Type;
* 类型转换接口函数根据给定的值和目标类型由用户自定义转换规则 * 类型转换接口函数根据给定的值和目标类型由用户自定义转换规则
* *
* @author looly * @author looly
* @since 5.8.0 * @since 6.0.0
*/ */
@FunctionalInterface @FunctionalInterface
public interface Converter { public interface Converter {
@ -36,6 +36,6 @@ public interface Converter {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
default <T> T convert(final Type targetType, final Object value, final T defaultValue) { default <T> 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);
} }
} }

View File

@ -1,30 +1,22 @@
package cn.hutool.core.convert; 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.AtomicBooleanConverter;
import cn.hutool.core.convert.impl.AtomicIntegerArrayConverter; import cn.hutool.core.convert.impl.AtomicIntegerArrayConverter;
import cn.hutool.core.convert.impl.AtomicLongArrayConverter; import cn.hutool.core.convert.impl.AtomicLongArrayConverter;
import cn.hutool.core.convert.impl.AtomicReferenceConverter; 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.BooleanConverter;
import cn.hutool.core.convert.impl.CalendarConverter; import cn.hutool.core.convert.impl.CalendarConverter;
import cn.hutool.core.convert.impl.CharacterConverter; import cn.hutool.core.convert.impl.CharacterConverter;
import cn.hutool.core.convert.impl.CharsetConverter; import cn.hutool.core.convert.impl.CharsetConverter;
import cn.hutool.core.convert.impl.ClassConverter; 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.CurrencyConverter;
import cn.hutool.core.convert.impl.DateConverter; import cn.hutool.core.convert.impl.DateConverter;
import cn.hutool.core.convert.impl.DurationConverter; 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.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.OptConverter;
import cn.hutool.core.convert.impl.OptionalConverter; import cn.hutool.core.convert.impl.OptionalConverter;
import cn.hutool.core.convert.impl.PathConverter; import cn.hutool.core.convert.impl.PathConverter;
import cn.hutool.core.convert.impl.PeriodConverter; 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.ReferenceConverter;
import cn.hutool.core.convert.impl.StackTraceElementConverter; import cn.hutool.core.convert.impl.StackTraceElementConverter;
import cn.hutool.core.convert.impl.StringConverter; 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.date.DateTime;
import cn.hutool.core.lang.Opt; import cn.hutool.core.lang.Opt;
import cn.hutool.core.reflect.ClassUtil; import cn.hutool.core.reflect.ClassUtil;
import cn.hutool.core.reflect.TypeReference;
import cn.hutool.core.reflect.TypeUtil; import cn.hutool.core.reflect.TypeUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ServiceLoaderUtil; import cn.hutool.core.util.ServiceLoaderUtil;
import java.io.Serializable; import java.io.Serializable;
@ -60,7 +50,6 @@ import java.time.Period;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAccessor;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collection;
import java.util.Currency; import java.util.Currency;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@ -74,18 +63,12 @@ import java.util.concurrent.atomic.AtomicLongArray;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
/** /**
* 转换器登记中心 * 基于类型注册的转换器转换器默认提供一些固定的类型转换用户可调用{@link #putCustom(Type, Converter)} 注册自定义转换规则
* <p>
* 将各种类型Convert对象放入登记中心通过convert方法查找目标类型对应的转换器将被转换对象转换之
* </p>
* <p>
* 在此类中存放着默认转换器和自定义转换器默认转换器是Hutool中预定义的一些转换器自定义转换器存放用户自定的转换器
* </p>
* *
* @author Looly * @author looly
* @since 6.0.0
*/ */
public class ConverterRegistry implements Serializable { public class RegisterConverter implements Converter, Serializable {
private static final long serialVersionUID = 1L;
/** /**
* 默认类型转换器 * 默认类型转换器
@ -96,50 +79,24 @@ public class ConverterRegistry implements Serializable {
*/ */
private volatile Map<Type, Converter> customConverterMap; private volatile Map<Type, Converter> 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(); registerDefault();
registerCustomBySpi(); registerCustomBySpi();
} }
/** @Override
* 登记自定义转换器 public Object convert(final Type targetType, final Object value) throws ConvertException {
* // 标准转换器
* @param type 转换的目标类型 final Converter converter = getConverter(targetType, true);
* @param converter 转换器 if (null != converter) {
* @return ConverterRegistry return converter.convert(targetType, value);
*/
public ConverterRegistry putCustom(final Type type, final Converter converter) {
if (null == customConverterMap) {
synchronized (this) {
if (null == customConverterMap) {
customConverterMap = new ConcurrentHashMap<>();
} }
}
} // 无法转换
customConverterMap.put(type, converter); throw new ConvertException("Can not convert from {}: [{}] to [{}]", value.getClass().getName(), value, targetType.getTypeName());
return this;
} }
/** /**
@ -186,164 +143,28 @@ public class ConverterRegistry implements Serializable {
} }
/** /**
* 转换值为指定类型 * 登记自定义转换器
* *
* @param <T> 转换的目标类型转换器转换到的类型 * @param type 转换的目标类型
* @param type 类型目标 * @param converter 转换器
* @param value 被转换值 * @return ConverterRegistry
* @param defaultValue 默认值
* @param isCustomFirst 是否自定义转换器优先
* @return 转换后的值
* @throws ConvertException 转换器不存在
*/ */
@SuppressWarnings("unchecked") public RegisterConverter putCustom(final Type type, final Converter converter) {
public <T> T convert(Type type, final Object value, final T defaultValue, final boolean isCustomFirst) throws ConvertException { if (null == customConverterMap) {
if (TypeUtil.isUnknown(type) && null == defaultValue) { synchronized (this) {
// 对于用户不指定目标类型的情况返回原值 if (null == customConverterMap) {
return (T) value; customConverterMap = new ConcurrentHashMap<>();
}
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<T> rowType = (Class<T>) TypeUtil.getClass(type);
if (null == rowType) {
if (null != defaultValue) {
rowType = (Class<T>) defaultValue.getClass();
} else {
throw new ConvertException("Can not get class from type: {}", type);
} }
} }
// 特殊类型转换包括CollectionMap强转Array等
final T result = convertSpecial(type, rowType, value, defaultValue);
if (null != result) {
return result;
} }
customConverterMap.put(type, converter);
// 尝试转Bean return this;
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());
}
/**
* 转换值为指定类型<br>
* 自定义转换器优先
*
* @param <T> 转换的目标类型转换器转换到的类型
* @param type 类型
* @param value
* @param defaultValue 默认值
* @return 转换后的值
* @throws ConvertException 转换器不存在
*/
public <T> T convert(final Type type, final Object value, final T defaultValue) throws ConvertException {
return convert(type, value, defaultValue, true);
}
/**
* 转换值为指定类型
*
* @param <T> 转换的目标类型转换器转换到的类型
* @param type 类型
* @param value
* @return 转换后的值默认为{@code null}
* @throws ConvertException 转换器不存在
*/
public <T> T convert(final Type type, final Object value) throws ConvertException {
return convert(type, value, null);
}
// ----------------------------------------------------------- Private method start
/**
* 特殊类型转换<br>
* 包括
*
* <pre>
* Collection
* Map
* 强转无需转换
* 数组
* </pre>
*
* @param <T> 转换的目标类型转换器转换到的类型
* @param type 类型
* @param value
* @param defaultValue 默认值
* @return 转换后的值
*/
@SuppressWarnings("unchecked")
private <T> T convertSpecial(final Type type, final Class<T> 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;
} }
/** /**
* 注册默认转换器 * 注册默认转换器
*
* @return 转换器
*/ */
private ConverterRegistry registerDefault() { private void registerDefault() {
defaultConverterMap = new ConcurrentHashMap<>(); defaultConverterMap = new ConcurrentHashMap<>();
// 包装类转换器 // 包装类转换器
@ -397,8 +218,6 @@ public class ConverterRegistry implements Serializable {
defaultConverterMap.put(StackTraceElement.class, new StackTraceElementConverter());// since 4.5.2 defaultConverterMap.put(StackTraceElement.class, new StackTraceElementConverter());// since 4.5.2
defaultConverterMap.put(Optional.class, new OptionalConverter());// since 5.0.0 defaultConverterMap.put(Optional.class, new OptionalConverter());// since 5.0.0
defaultConverterMap.put(Opt.class, new OptConverter());// since 5.7.16 defaultConverterMap.put(Opt.class, new OptConverter());// since 5.7.16
return this;
} }
/** /**
@ -416,5 +235,4 @@ public class ConverterRegistry implements Serializable {
} }
}); });
} }
// ----------------------------------------------------------- Private method end
} }

View File

@ -1,7 +1,7 @@
package cn.hutool.core.convert.impl; package cn.hutool.core.convert.impl;
import cn.hutool.core.convert.AbstractConverter; 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 cn.hutool.core.reflect.TypeUtil;
import java.lang.reflect.Type; import java.lang.reflect.Type;
@ -23,7 +23,7 @@ public class AtomicReferenceConverter extends AbstractConverter {
Object targetValue = null; Object targetValue = null;
final Type paramType = TypeUtil.getTypeArgument(AtomicReference.class); final Type paramType = TypeUtil.getTypeArgument(AtomicReference.class);
if(false == TypeUtil.isUnknown(paramType)){ if(false == TypeUtil.isUnknown(paramType)){
targetValue = ConverterRegistry.getInstance().convert(paramType, value); targetValue = CompositeConverter.getInstance().convert(paramType, value);
} }
if(null == targetValue){ if(null == targetValue){
targetValue = value; targetValue = value;

View File

@ -2,7 +2,7 @@ package cn.hutool.core.convert.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.ConvertException; 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.convert.Converter;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.reflect.TypeReference; import cn.hutool.core.reflect.TypeReference;
@ -26,7 +26,7 @@ public class MapConverter implements Converter, Serializable {
public static MapConverter INSTANCE = new MapConverter(); public static MapConverter INSTANCE = new MapConverter();
@Override @Override
public Object convert(Type targetType, Object value) throws ConvertException { public Object convert(Type targetType, final Object value) throws ConvertException {
if (targetType instanceof TypeReference) { if (targetType instanceof TypeReference) {
targetType = ((TypeReference<?>) targetType).getType(); targetType = ((TypeReference<?>) targetType).getType();
} }
@ -79,11 +79,11 @@ public class MapConverter implements Converter, Serializable {
* @param targetMap 目标Map * @param targetMap 目标Map
*/ */
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
private void convertMapToMap(Type keyType, Type valueType, final Map<?, ?> srcMap, final Map targetMap) { private void convertMapToMap(final Type keyType, final Type valueType, final Map<?, ?> srcMap, final Map targetMap) {
final ConverterRegistry convert = ConverterRegistry.getInstance(); final CompositeConverter convert = CompositeConverter.getInstance();
srcMap.forEach((key, value) -> { srcMap.forEach((key, value) -> {
key = TypeUtil.isUnknown(keyType) ? key : convert.convert(keyType, key); key = TypeUtil.isUnknown(keyType) ? key : convert.convert(keyType, key, null);
value = TypeUtil.isUnknown(valueType) ? value : convert.convert(valueType, value); value = TypeUtil.isUnknown(valueType) ? value : convert.convert(valueType, value, null);
targetMap.put(key, value); targetMap.put(key, value);
}); });
} }

View File

@ -1,7 +1,7 @@
package cn.hutool.core.convert.impl; package cn.hutool.core.convert.impl;
import cn.hutool.core.convert.AbstractConverter; 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.text.StrUtil;
import cn.hutool.core.reflect.TypeUtil; import cn.hutool.core.reflect.TypeUtil;
@ -30,7 +30,7 @@ public class ReferenceConverter extends AbstractConverter {
Object targetValue = null; Object targetValue = null;
final Type paramType = TypeUtil.getTypeArgument(targetClass); final Type paramType = TypeUtil.getTypeArgument(targetClass);
if(false == TypeUtil.isUnknown(paramType)){ if(false == TypeUtil.isUnknown(paramType)){
targetValue = ConverterRegistry.getInstance().convert(paramType, value); targetValue = CompositeConverter.getInstance().convert(paramType, value);
} }
if(null == targetValue){ if(null == targetValue){
targetValue = value; targetValue = value;

View File

@ -10,26 +10,26 @@ import java.lang.reflect.Type;
* @author Looly * @author Looly
* *
*/ */
public class ConverterRegistryTest { public class CompositeConverterTest {
@Test @Test
public void getConverterTest() { public void getConverterTest() {
final Converter converter = ConverterRegistry.getInstance().getConverter(CharSequence.class, false); final Converter converter = CompositeConverter.getInstance().getConverter(CharSequence.class, false);
Assert.assertNotNull(converter); Assert.assertNotNull(converter);
} }
@Test @Test
public void customTest(){ public void customTest(){
final int a = 454553; 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); Assert.assertEquals("454553", result);
//此处做为示例自定义CharSequence转换因为Hutool中已经提供CharSequence转换请尽量不要替换 //此处做为示例自定义CharSequence转换因为Hutool中已经提供CharSequence转换请尽量不要替换
//替换可能引发关联转换异常例如覆盖CharSequence转换会影响全局 //替换可能引发关联转换异常例如覆盖CharSequence转换会影响全局
converterRegistry.putCustom(CharSequence.class, new CustomConverter()); compositeConverter.putCustom(CharSequence.class, new CustomConverter());
result = converterRegistry.convert(CharSequence.class, a); result = (CharSequence) compositeConverter.convert(CharSequence.class, a);
Assert.assertEquals("Custom: 454553", result); Assert.assertEquals("Custom: 454553", result);
} }

View File

@ -81,28 +81,28 @@ public class ConvertTest {
final String a = " 34232"; final String a = " 34232";
final Integer aInteger = Convert.toInt(a); final Integer aInteger = Convert.toInt(a);
Assert.assertEquals(Integer.valueOf(34232), aInteger); 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); Assert.assertEquals(34232, aInt);
// 带小数测试 // 带小数测试
final String b = " 34232.00"; final String b = " 34232.00";
final Integer bInteger = Convert.toInt(b); final Integer bInteger = Convert.toInt(b);
Assert.assertEquals(Integer.valueOf(34232), bInteger); 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); Assert.assertEquals(34232, bInt);
// boolean测试 // boolean测试
final boolean c = true; final boolean c = true;
final Integer cInteger = Convert.toInt(c); final Integer cInteger = Convert.toInt(c);
Assert.assertEquals(Integer.valueOf(1), cInteger); 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); Assert.assertEquals(1, cInt);
// boolean测试 // boolean测试
final String d = "08"; final String d = "08";
final Integer dInteger = Convert.toInt(d); final Integer dInteger = Convert.toInt(d);
Assert.assertEquals(Integer.valueOf(8), dInteger); 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); Assert.assertEquals(8, dInt);
} }
@ -124,28 +124,28 @@ public class ConvertTest {
final String a = " 342324545435435"; final String a = " 342324545435435";
final Long aLong = Convert.toLong(a); final Long aLong = Convert.toLong(a);
Assert.assertEquals(Long.valueOf(342324545435435L), aLong); 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); Assert.assertEquals(342324545435435L, aLong2);
// 带小数测试 // 带小数测试
final String b = " 342324545435435.245435435"; final String b = " 342324545435435.245435435";
final Long bLong = Convert.toLong(b); final Long bLong = Convert.toLong(b);
Assert.assertEquals(Long.valueOf(342324545435435L), bLong); 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); Assert.assertEquals(342324545435435L, bLong2);
// boolean测试 // boolean测试
final boolean c = true; final boolean c = true;
final Long cLong = Convert.toLong(c); final Long cLong = Convert.toLong(c);
Assert.assertEquals(Long.valueOf(1), cLong); 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); Assert.assertEquals(1, cLong2);
// boolean测试 // boolean测试
final String d = "08"; final String d = "08";
final Long dLong = Convert.toLong(d); final Long dLong = Convert.toLong(d);
Assert.assertEquals(Long.valueOf(8), dLong); 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); Assert.assertEquals(8, dLong2);
} }

View File

@ -79,11 +79,11 @@ public class ConvertToArrayTest {
//数组转数组测试 //数组转数组测试
final int[] a = new int[]{1,2,3,4}; 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); 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); Assert.assertArrayEquals(new byte[]{1, 2, 3, 4}, resultBytes);
//字符串转数组 //字符串转数组

View File

@ -3,7 +3,7 @@ package cn.hutool.json.convert;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.ConvertException; import cn.hutool.core.convert.ConvertException;
import cn.hutool.core.convert.Converter; 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.BeanConverter;
import cn.hutool.core.convert.impl.DateConverter; import cn.hutool.core.convert.impl.DateConverter;
import cn.hutool.core.convert.impl.TemporalAccessorConverter; import cn.hutool.core.convert.impl.TemporalAccessorConverter;
@ -34,10 +34,10 @@ public class JSONConverter implements Converter {
public static JSONConverter INSTANCE = new JSONConverter(); public static JSONConverter INSTANCE = new JSONConverter();
private static final ConverterRegistry registry; private static final CompositeConverter registry;
static { static {
// 注册到转换中心 // 注册到转换中心
registry = new ConverterRegistry(); registry = new CompositeConverter();
registry.putCustom(JSON.class, INSTANCE); registry.putCustom(JSON.class, INSTANCE);
registry.putCustom(JSONObject.class, INSTANCE); registry.putCustom(JSONObject.class, INSTANCE);
registry.putCustom(JSONArray.class, INSTANCE); registry.putCustom(JSONArray.class, INSTANCE);