mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-03 16:24:31 +08:00
[bug修复] JsonUtil.toBean泛型数组类型丢失
This commit is contained in:
parent
bd94c09e91
commit
732bea6d0b
@ -2,8 +2,10 @@ package cn.hutool.core.lang.reflect;
|
|||||||
|
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.map.WeakConcurrentMap;
|
import cn.hutool.core.map.WeakConcurrentMap;
|
||||||
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.hutool.core.util.TypeUtil;
|
import cn.hutool.core.util.TypeUtil;
|
||||||
|
|
||||||
|
import java.lang.reflect.GenericArrayType;
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.lang.reflect.TypeVariable;
|
import java.lang.reflect.TypeVariable;
|
||||||
@ -57,6 +59,22 @@ public class ActualTypeMapperPool {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Type getActualType(Type type, GenericArrayType genericArrayType) {
|
||||||
|
final Map<Type, Type> typeTypeMap = get(type);
|
||||||
|
Type actualType = typeTypeMap.get(genericArrayType);
|
||||||
|
|
||||||
|
if (actualType == null) {
|
||||||
|
Type componentType = typeTypeMap.get(genericArrayType.getGenericComponentType());
|
||||||
|
if (!(componentType instanceof Class<?>)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
actualType = ArrayUtil.getArrayType((Class<?>) componentType);
|
||||||
|
typeTypeMap.put(genericArrayType, actualType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return actualType;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取指定泛型变量对应的真实类型<br>
|
* 获取指定泛型变量对应的真实类型<br>
|
||||||
* 由于子类中泛型参数实现和父类(接口)中泛型定义位置是一一对应的,因此可以通过对应关系找到泛型实现类型<br>
|
* 由于子类中泛型参数实现和父类(接口)中泛型定义位置是一一对应的,因此可以通过对应关系找到泛型实现类型<br>
|
||||||
|
@ -3,12 +3,7 @@ package cn.hutool.core.util;
|
|||||||
import cn.hutool.core.lang.ParameterizedTypeImpl;
|
import cn.hutool.core.lang.ParameterizedTypeImpl;
|
||||||
import cn.hutool.core.lang.reflect.ActualTypeMapperPool;
|
import cn.hutool.core.lang.reflect.ActualTypeMapperPool;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.*;
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.lang.reflect.TypeVariable;
|
|
||||||
import java.lang.reflect.WildcardType;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -412,6 +407,9 @@ public class TypeUtil {
|
|||||||
if (typeVariable instanceof TypeVariable) {
|
if (typeVariable instanceof TypeVariable) {
|
||||||
return ActualTypeMapperPool.getActualType(type, (TypeVariable<?>) typeVariable);
|
return ActualTypeMapperPool.getActualType(type, (TypeVariable<?>) typeVariable);
|
||||||
}
|
}
|
||||||
|
if (typeVariable instanceof GenericArrayType) {
|
||||||
|
return ActualTypeMapperPool.getActualType(type, (GenericArrayType) typeVariable);
|
||||||
|
}
|
||||||
|
|
||||||
// 没有需要替换的泛型变量,原样输出
|
// 没有需要替换的泛型变量,原样输出
|
||||||
return typeVariable;
|
return typeVariable;
|
||||||
|
@ -4,8 +4,12 @@ import java.lang.reflect.Method;
|
|||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.TypeReference;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public class TypeUtilTest {
|
public class TypeUtilTest {
|
||||||
@ -97,4 +101,29 @@ public class TypeUtilTest {
|
|||||||
private T level;
|
private T level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fix github:issue#3873
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void getActualTypeForGenericArrayTest() {
|
||||||
|
TypeReference<GenericArray<GenericArrayEle>> typeReference = new TypeReference<GenericArray<GenericArrayEle>>() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
Type levelType = TypeUtil.getFieldType(GenericArray.class, "level");
|
||||||
|
Type actualType = TypeUtil.getActualType(typeReference.getType(), levelType);
|
||||||
|
assertEquals(ArrayUtil.getArrayType(GenericArrayEle.class), actualType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class GenericArray<T> {
|
||||||
|
private T[] level;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class GenericArrayEle {
|
||||||
|
private Long uid;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,9 @@ import cn.hutool.core.collection.CollectionUtil;
|
|||||||
import cn.hutool.core.collection.ListUtil;
|
import cn.hutool.core.collection.ListUtil;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.lang.Console;
|
import cn.hutool.core.lang.Console;
|
||||||
|
import cn.hutool.core.lang.TypeReference;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.hutool.core.util.NumberUtil;
|
import cn.hutool.core.util.NumberUtil;
|
||||||
import cn.hutool.json.test.bean.Price;
|
import cn.hutool.json.test.bean.Price;
|
||||||
import cn.hutool.json.test.bean.UserA;
|
import cn.hutool.json.test.bean.UserA;
|
||||||
@ -290,4 +292,27 @@ public class JSONUtilTest {
|
|||||||
final String jsonStr = JSONUtil.toJsonStr(userId);
|
final String jsonStr = JSONUtil.toJsonStr(userId);
|
||||||
assertEquals("{}", jsonStr);
|
assertEquals("{}", jsonStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型引用数组泛型丢失
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void issue3873Test() {
|
||||||
|
String json = "{\"results\":[{\"uid\":\"1\"}],\"offset\":0,\"limit\":20,\"total\":0}";
|
||||||
|
Results<Index> deserialize = JSONUtil.toBean(json, (new TypeReference<Results<Index>>() {
|
||||||
|
}), false);
|
||||||
|
|
||||||
|
assertEquals(Results.class, deserialize.getClass());
|
||||||
|
assertEquals(ArrayUtil.getArrayType(Index.class), deserialize.results.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Results<T> {
|
||||||
|
public T[] results;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Index {
|
||||||
|
public String uid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user