From 646815c3de88af87691aad76be2a9b498be0f2d4 Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 4 Nov 2021 02:15:00 +0800 Subject: [PATCH] add test --- .../core/convert/impl/StringConverter.java | 3 + .../lang/reflect/ActualTypeMapperPool.java | 19 +++++- .../reflect/ActualTypeMapperPoolTest.java | 60 +++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 hutool-core/src/test/java/cn/hutool/core/lang/reflect/ActualTypeMapperPoolTest.java diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/StringConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/StringConverter.java index 89001aa8e..b11491e58 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/impl/StringConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/StringConverter.java @@ -8,6 +8,7 @@ import cn.hutool.core.util.XmlUtil; import java.io.InputStream; import java.io.Reader; +import java.lang.reflect.Type; import java.sql.Blob; import java.sql.Clob; import java.sql.SQLException; @@ -31,6 +32,8 @@ public class StringConverter extends AbstractConverter { return clobToStr((Clob) value); } else if (value instanceof Blob) { return blobToStr((Blob) value); + } else if (value instanceof Type) { + return ((Type) value).getTypeName(); } // 其它情况 diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/reflect/ActualTypeMapperPool.java b/hutool-core/src/main/java/cn/hutool/core/lang/reflect/ActualTypeMapperPool.java index 88dd1f3c1..5bb5f6d5f 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/reflect/ActualTypeMapperPool.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/reflect/ActualTypeMapperPool.java @@ -1,5 +1,6 @@ package cn.hutool.core.lang.reflect; +import cn.hutool.core.convert.Convert; import cn.hutool.core.lang.SimpleCache; import cn.hutool.core.util.TypeUtil; @@ -29,6 +30,17 @@ public class ActualTypeMapperPool { return CACHE.get(type, () -> createTypeMap(type)); } + /** + * 获取泛型变量名(字符串)和泛型实际类型的对应关系Map + * + * @param type 被解析的包含泛型参数的类 + * @return 泛型对应关系Map + * @since 5.7.16 + */ + public static Map getStrKeyMap(Type type){ + return Convert.toMap(String.class, Type.class, get(type)); + } + /** * 获得泛型变量对应的泛型实际类型,如果此变量没有对应的实际类型,返回null * @@ -89,8 +101,13 @@ public class ActualTypeMapperPool { final Class rawType = (Class) parameterizedType.getRawType(); final Type[] typeParameters = rawType.getTypeParameters(); + Type value; for (int i = 0; i < typeParameters.length; i++) { - typeMap.put(typeParameters[i], typeArguments[i]); + value = typeArguments[i]; + // 跳过泛型变量对应泛型变量的情况 + if(false == value instanceof TypeVariable){ + typeMap.put(typeParameters[i], value); + } } type = rawType; diff --git a/hutool-core/src/test/java/cn/hutool/core/lang/reflect/ActualTypeMapperPoolTest.java b/hutool-core/src/test/java/cn/hutool/core/lang/reflect/ActualTypeMapperPoolTest.java new file mode 100644 index 000000000..8ccd2087f --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/lang/reflect/ActualTypeMapperPoolTest.java @@ -0,0 +1,60 @@ +package cn.hutool.core.lang.reflect; + +import org.junit.Assert; +import org.junit.Test; + +import java.lang.reflect.Type; +import java.util.Map; + +/** + * 见:https://gitee.com/dromara/hutool/pulls/447/files + * + * TODO 同时继承泛型和实现泛型接口需要解析,此处为F + */ +public class ActualTypeMapperPoolTest { + + @Test + public void getTypeArgumentTest(){ + final Map typeTypeMap = ActualTypeMapperPool.get(FinalClass.class); + typeTypeMap.forEach((key, value)->{ + if("A".equals(key.getTypeName())){ + Assert.assertEquals(Character.class, value); + } else if("B".equals(key.getTypeName())){ + Assert.assertEquals(Boolean.class, value); + } else if("C".equals(key.getTypeName())){ + Assert.assertEquals(String.class, value); + } else if("D".equals(key.getTypeName())){ + Assert.assertEquals(Double.class, value); + } else if("E".equals(key.getTypeName())){ + Assert.assertEquals(Integer.class, value); + } + }); + } + + @Test + public void getTypeArgumentStrKeyTest(){ + final Map typeTypeMap = ActualTypeMapperPool.getStrKeyMap(FinalClass.class); + typeTypeMap.forEach((key, value)->{ + if("A".equals(key)){ + Assert.assertEquals(Character.class, value); + } else if("B".equals(key)){ + Assert.assertEquals(Boolean.class, value); + } else if("C".equals(key)){ + Assert.assertEquals(String.class, value); + } else if("D".equals(key)){ + Assert.assertEquals(Double.class, value); + } else if("E".equals(key)){ + Assert.assertEquals(Integer.class, value); + } + }); + } + + public interface BaseInterface {} + public interface FirstInterface extends BaseInterface {} + public interface SecondInterface extends BaseInterface {} + + public static class BaseClass implements FirstInterface {} + public static class FirstClass extends BaseClass implements SecondInterface {} + public static class SecondClass extends FirstClass {} + public static class FinalClass extends SecondClass {} +}