From bdbe51fe3126ae45543ba0f2fd49b88919690964 Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 26 Nov 2025 16:30:29 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D`ReflectUtil.newInstanceIfPos?= =?UTF-8?q?sible`=E4=BC=A0=E5=85=A5Object=E9=80=BB=E8=BE=91=E9=94=99?= =?UTF-8?q?=E8=AF=AF=EF=BC=88pr#4160@Github=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../v7/core/reflect/ConstructorUtil.java | 4 +- .../creator/PossibleObjectCreator.java | 36 ++++++---- .../v7/core/reflect/ConstructorUtilTest.java | 69 +++++++++++++++---- 3 files changed, 81 insertions(+), 28 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/v7/core/reflect/ConstructorUtil.java b/hutool-core/src/main/java/cn/hutool/v7/core/reflect/ConstructorUtil.java index 7d537916c5..da4ce717c4 100644 --- a/hutool-core/src/main/java/cn/hutool/v7/core/reflect/ConstructorUtil.java +++ b/hutool-core/src/main/java/cn/hutool/v7/core/reflect/ConstructorUtil.java @@ -133,9 +133,11 @@ public class ConstructorUtil { * 对于某些特殊的接口,按照其默认实现实例化,例如: *
 	 *     Map       -》 HashMap
-	 *     Collction -》 ArrayList
 	 *     List      -》 ArrayList
 	 *     Set       -》 HashSet
+	 *     Queue     -》 LinkedList
+	 *     Deque     -》 LinkedList
+	 *     Collection-》 ArrayList
 	 * 
* * @param 对象类型 diff --git a/hutool-core/src/main/java/cn/hutool/v7/core/reflect/creator/PossibleObjectCreator.java b/hutool-core/src/main/java/cn/hutool/v7/core/reflect/creator/PossibleObjectCreator.java index 8165292f30..0d247cb73e 100644 --- a/hutool-core/src/main/java/cn/hutool/v7/core/reflect/creator/PossibleObjectCreator.java +++ b/hutool-core/src/main/java/cn/hutool/v7/core/reflect/creator/PossibleObjectCreator.java @@ -46,7 +46,7 @@ import java.util.*; * * @param 对象类型 */ -public class PossibleObjectCreator implements ObjectCreator { +public record PossibleObjectCreator(Class clazz) implements ObjectCreator { /** * 创建默认的对象实例化器 @@ -59,8 +59,6 @@ public class PossibleObjectCreator implements ObjectCreator { return new PossibleObjectCreator<>(clazz); } - final Class clazz; - /** * 构造 * @@ -120,20 +118,34 @@ public class PossibleObjectCreator implements ObjectCreator { } /** - * 某些特殊接口的实例化按照默认实现进行 + * 对于某些特殊的接口,按照其默认实现实例化,例如: + *
+	 *     Map       -》 HashMap
+	 *     List      -》 ArrayList
+	 *     Set       -》 HashSet
+	 *     Queue     -》 LinkedList
+	 *     Deque     -》 LinkedList
+	 *     Collection-》 ArrayList
+	 * 
* * @param type 类型 * @return 默认类型 */ private static Class resolveType(final Class type) { - if (type.isAssignableFrom(AbstractMap.class)) { - return HashMap.class; - } else if (type.isAssignableFrom(List.class)) { - return ArrayList.class; - } else if (type == SortedSet.class) { - return TreeSet.class; - } else if (type.isAssignableFrom(Set.class)) { - return HashSet.class; + if (Object.class != type) { + if (type.isAssignableFrom(AbstractMap.class)) { + return HashMap.class; + } else if (type.isAssignableFrom(List.class)) { + return ArrayList.class; + } else if (type == SortedSet.class) { + return TreeSet.class; + } else if (type.isAssignableFrom(Set.class)) { + return HashSet.class; + } else if (type.isAssignableFrom(Queue.class)) { + return LinkedList.class; + } else if (type.isAssignableFrom(Deque.class)) { + return LinkedList.class; + } } return type; diff --git a/hutool-core/src/test/java/cn/hutool/v7/core/reflect/ConstructorUtilTest.java b/hutool-core/src/test/java/cn/hutool/v7/core/reflect/ConstructorUtilTest.java index e0cafa1eaa..b7494bb9a1 100644 --- a/hutool-core/src/test/java/cn/hutool/v7/core/reflect/ConstructorUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/v7/core/reflect/ConstructorUtilTest.java @@ -16,42 +16,42 @@ package cn.hutool.v7.core.reflect; +import cn.hutool.v7.core.date.Week; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import cn.hutool.v7.core.date.Week; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import java.util.Collection; -import java.util.Hashtable; -import java.util.Map; +import java.util.*; + +import static org.junit.jupiter.api.Assertions.*; public class ConstructorUtilTest { @Test public void noneStaticInnerClassTest() { final ReflectTestBeans.NoneStaticClass testAClass = ConstructorUtil.newInstanceIfPossible(ReflectTestBeans.NoneStaticClass.class); - Assertions.assertNotNull(testAClass); - Assertions.assertEquals(2, testAClass.getA()); + assertNotNull(testAClass); + assertEquals(2, testAClass.getA()); } @Test public void newInstanceIfPossibleTest(){ //noinspection ConstantConditions final int intValue = ConstructorUtil.newInstanceIfPossible(int.class); - Assertions.assertEquals(0, intValue); + assertEquals(0, intValue); final Integer integer = ConstructorUtil.newInstanceIfPossible(Integer.class); - Assertions.assertEquals(Integer.valueOf(0), integer); + assertEquals(Integer.valueOf(0), integer); final Map map = ConstructorUtil.newInstanceIfPossible(Map.class); - Assertions.assertNotNull(map); + assertNotNull(map); final Collection collection = ConstructorUtil.newInstanceIfPossible(Collection.class); - Assertions.assertNotNull(collection); + assertNotNull(collection); final Week week = ConstructorUtil.newInstanceIfPossible(Week.class); - Assertions.assertEquals(Week.SUNDAY, week); + assertEquals(Week.SUNDAY, week); final int[] intArray = ConstructorUtil.newInstanceIfPossible(int[].class); Assertions.assertArrayEquals(new int[0], intArray); @@ -61,20 +61,20 @@ public class ConstructorUtilTest { void newInstanceTest() { final TestBean testBean = ConstructorUtil.newInstance(TestBean.class); Assertions.assertNull(testBean.getA()); - Assertions.assertEquals(0, testBean.getB()); + assertEquals(0, testBean.getB()); } @Test void newInstanceAllArgsTest() { final TestBean testBean = ConstructorUtil.newInstance(TestBean.class, "aValue", 1); - Assertions.assertEquals("aValue", testBean.getA()); - Assertions.assertEquals(1, testBean.getB()); + assertEquals("aValue", testBean.getA()); + assertEquals(1, testBean.getB()); } @Test void newInstanceHashtableTest() { final Hashtable testBean = ConstructorUtil.newInstance(Hashtable.class); - Assertions.assertNotNull(testBean); + assertNotNull(testBean); } @Data @@ -84,4 +84,43 @@ public class ConstructorUtilTest { private String a; private int b; } + + @Test + public void newInstanceIfPossibleTest2() { + // 测试Object.class不应该被错误地实例化为HashMap,应该返回Object实例 + final Object objectInstance = ConstructorUtil.newInstanceIfPossible(Object.class); + assertNotNull(objectInstance); + assertEquals(Object.class, objectInstance.getClass()); + + // 测试Map.class能够正确实例化为HashMap + final Map mapInstance = ConstructorUtil.newInstanceIfPossible(Map.class); + assertNotNull(mapInstance); + assertInstanceOf(HashMap.class, mapInstance); + + // 测试Collection.class能够正确实例化为ArrayList + final Collection collectionInstance = ConstructorUtil.newInstanceIfPossible(Collection.class); + assertNotNull(collectionInstance); + assertInstanceOf(ArrayList.class, collectionInstance); + + + // 测试List.class能够正确实例化为ArrayList + final List listInstance = ConstructorUtil.newInstanceIfPossible(List.class); + assertNotNull(listInstance); + assertInstanceOf(ArrayList.class, listInstance); + + // 测试Set.class能够正确实例化为HashSet + final Set setInstance = ConstructorUtil.newInstanceIfPossible(Set.class); + assertNotNull(setInstance); + assertInstanceOf(HashSet.class, setInstance); + + // 测试Queue接口能够正确实例化为LinkedList + final Queue queueInstance = ConstructorUtil.newInstanceIfPossible(Queue.class); + assertNotNull(queueInstance); + assertInstanceOf(LinkedList.class, queueInstance); + + // 测试Deque接口能够正确实例化为LinkedList + final Deque dequeInstance = ConstructorUtil.newInstanceIfPossible(Deque.class); + assertNotNull(dequeInstance); + assertInstanceOf(LinkedList.class, dequeInstance); + } }