diff --git a/CHANGELOG.md b/CHANGELOG.md index 0debc4469..a1afd293c 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ * 【extra 】 增加JakartaServletUtil(issue#2271@Github) * 【poi 】 ExcelWriter支持重复别名的数据写出(issue#I53APY@Gitee) * 【core 】 增加Hashids(issue#I53APY@Gitee) +* 【core 】 ReflectUtil.newInstanceIfPossible添加枚举、数组等类型的默认实现 ### 🐞Bug修复 * 【core 】 修复StrUtil.firstNonX非static问题(issue#2257@Github) diff --git a/hutool-core/src/main/java/cn/hutool/core/text/StrMatcher.java b/hutool-core/src/main/java/cn/hutool/core/text/StrMatcher.java index 1b5bac02d..ccc59f87f 100644 --- a/hutool-core/src/main/java/cn/hutool/core/text/StrMatcher.java +++ b/hutool-core/src/main/java/cn/hutool/core/text/StrMatcher.java @@ -35,6 +35,7 @@ public class StrMatcher { /** * 匹配并提取匹配到的内容 + * * @param text 被匹配的文本 * @return 匹配的map,key为变量名,value为匹配到的值 */ @@ -49,7 +50,7 @@ public class StrMatcher { key = StrUtil.sub(part, 2, part.length() - 1); } else { to = text.indexOf(part, from); - if(to < 0){ + if (to < 0) { //普通字符串未匹配到,说明整个模式不能匹配,返回空 return MapUtil.empty(); } @@ -73,6 +74,7 @@ public class StrMatcher { /** * 解析表达式 + * * @param pattern 表达式,使用${XXXX}作为变量占位符 * @return 表达式 */ diff --git a/hutool-core/src/main/java/cn/hutool/core/text/StrTemplate.java b/hutool-core/src/main/java/cn/hutool/core/text/StrTemplate.java deleted file mode 100755 index 5293e7918..000000000 --- a/hutool-core/src/main/java/cn/hutool/core/text/StrTemplate.java +++ /dev/null @@ -1,4 +0,0 @@ -package cn.hutool.core.text; - -public class StrTemplate { -} diff --git a/hutool-core/src/main/java/cn/hutool/core/util/ClassUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/ClassUtil.java index a25d41504..e697fed49 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/ClassUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/ClassUtil.java @@ -999,26 +999,44 @@ public class ClassUtil { * @since 3.0.8 */ public static Object getDefaultValue(Class clazz) { + // 原始类型 if (clazz.isPrimitive()) { - if (long.class == clazz) { - return 0L; - } else if (int.class == clazz) { - return 0; - } else if (short.class == clazz) { - return (short) 0; - } else if (char.class == clazz) { - return (char) 0; - } else if (byte.class == clazz) { - return (byte) 0; - } else if (double.class == clazz) { - return 0D; - } else if (float.class == clazz) { - return 0f; - } else if (boolean.class == clazz) { - return false; - } + return getPrimitiveDefaultValue(clazz); } + return null; + } + /** + * 获取指定原始类型分的默认值
+ * 默认值规则为: + * + *
+	 * 1、如果为原始类型,返回0
+	 * 2、非原始类型返回{@code null}
+	 * 
+ * + * @param clazz 类 + * @return 默认值 + * @since 5.8.0 + */ + public static Object getPrimitiveDefaultValue(Class clazz) { + if (long.class == clazz) { + return 0L; + } else if (int.class == clazz) { + return 0; + } else if (short.class == clazz) { + return (short) 0; + } else if (char.class == clazz) { + return (char) 0; + } else if (byte.class == clazz) { + return (byte) 0; + } else if (double.class == clazz) { + return 0D; + } else if (float.class == clazz) { + return 0f; + } else if (boolean.class == clazz) { + return false; + } return null; } diff --git a/hutool-core/src/main/java/cn/hutool/core/util/ReflectUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/ReflectUtil.java index b9c3ab637..39d94196e 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/ReflectUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/ReflectUtil.java @@ -13,6 +13,7 @@ import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.WeakConcurrentMap; import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -864,30 +865,45 @@ public class ReflectUtil { * * * @param 对象类型 - * @param beanClass 被构造的类 + * @param type 被构造的类 * @return 构造后的对象,构造失败返回{@code null} */ @SuppressWarnings("unchecked") - public static T newInstanceIfPossible(Class beanClass) { - Assert.notNull(beanClass); + public static T newInstanceIfPossible(Class type) { + Assert.notNull(type); + + // 原始类型 + if(type.isPrimitive()){ + return (T) ClassUtil.getPrimitiveDefaultValue(type); + } // 某些特殊接口的实例化按照默认实现进行 - if (beanClass.isAssignableFrom(AbstractMap.class)) { - beanClass = (Class) HashMap.class; - } else if (beanClass.isAssignableFrom(List.class)) { - beanClass = (Class) ArrayList.class; - } else if (beanClass.isAssignableFrom(Set.class)) { - beanClass = (Class) HashSet.class; + if (type.isAssignableFrom(AbstractMap.class)) { + type = (Class) HashMap.class; + } else if (type.isAssignableFrom(List.class)) { + type = (Class) ArrayList.class; + } else if (type.isAssignableFrom(Set.class)) { + type = (Class) HashSet.class; } try { - return newInstance(beanClass); + return newInstance(type); } catch (Exception e) { // ignore // 默认构造不存在的情况下查找其它构造 } - final Constructor[] constructors = getConstructors(beanClass); + // 枚举 + if (type.isEnum()) { + return type.getEnumConstants()[0]; + } + + // 数组 + if (type.isArray()) { + return (T) Array.newInstance(type.getComponentType(), 0); + } + + final Constructor[] constructors = getConstructors(type); Class[] parameterTypes; for (Constructor constructor : constructors) { parameterTypes = constructor.getParameterTypes(); diff --git a/hutool-core/src/test/java/cn/hutool/core/util/ReflectUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/ReflectUtilTest.java index 6affbabb6..7792804a8 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/ReflectUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/ReflectUtilTest.java @@ -2,6 +2,7 @@ package cn.hutool.core.util; import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.TimeInterval; +import cn.hutool.core.date.Week; import cn.hutool.core.lang.Console; import cn.hutool.core.lang.test.bean.ExamInfoDict; import cn.hutool.core.util.ClassUtilTest.TestSubClass; @@ -12,6 +13,8 @@ import org.junit.Test; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Map; /** * 反射工具类单元测试 @@ -202,10 +205,13 @@ public class ReflectUtilTest { } interface TestInterface1 { + @SuppressWarnings("unused") void getA(); + @SuppressWarnings("unused") void getB(); + @SuppressWarnings("unused") default void getC() { } @@ -220,6 +226,7 @@ public class ReflectUtilTest { void get3(); } + @SuppressWarnings("InnerClassMayBeStatic") class C1 implements TestInterface2 { @Override @@ -239,4 +246,26 @@ public class ReflectUtilTest { } } + + @Test + public void newInstanceIfPossibleTest(){ + //noinspection ConstantConditions + int intValue = ReflectUtil.newInstanceIfPossible(int.class); + Assert.assertEquals(0, intValue); + + Integer integer = ReflectUtil.newInstanceIfPossible(Integer.class); + Assert.assertEquals(new Integer(0), integer); + + Map map = ReflectUtil.newInstanceIfPossible(Map.class); + Assert.assertNotNull(map); + + Collection collection = ReflectUtil.newInstanceIfPossible(Collection.class); + Assert.assertNotNull(collection); + + Week week = ReflectUtil.newInstanceIfPossible(Week.class); + Assert.assertEquals(Week.SUNDAY, week); + + int[] intArray = ReflectUtil.newInstanceIfPossible(int[].class); + Assert.assertArrayEquals(new int[0], intArray); + } }