1
0
mirror of https://gitee.com/dromara/hutool.git synced 2025-04-05 17:37:59 +08:00
This commit is contained in:
Looly 2022-04-25 17:23:31 +08:00
parent 940d1cbe31
commit 82f5b2b154
6 changed files with 95 additions and 33 deletions
CHANGELOG.md
hutool-core/src
main/java/cn/hutool/core
test/java/cn/hutool/core/util

View File

@ -20,6 +20,7 @@
* 【extra 】 增加JakartaServletUtilissue#2271@Github
* 【poi 】 ExcelWriter支持重复别名的数据写出issue#I53APY@Gitee
* 【core 】 增加Hashidsissue#I53APY@Gitee
* 【core 】 ReflectUtil.newInstanceIfPossible添加枚举、数组等类型的默认实现
### 🐞Bug修复
* 【core 】 修复StrUtil.firstNonX非static问题issue#2257@Github

View File

@ -35,6 +35,7 @@ public class StrMatcher {
/**
* 匹配并提取匹配到的内容
*
* @param text 被匹配的文本
* @return 匹配的mapkey为变量名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 表达式
*/

View File

@ -1,4 +0,0 @@
package cn.hutool.core.text;
public class StrTemplate {
}

View File

@ -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;
}
/**
* 获取指定原始类型分的默认值<br>
* 默认值规则为
*
* <pre>
* 1如果为原始类型返回0
* 2非原始类型返回{@code null}
* </pre>
*
* @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;
}

View File

@ -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 {
* </pre>
*
* @param <T> 对象类型
* @param beanClass 被构造的类
* @param type 被构造的类
* @return 构造后的对象构造失败返回{@code null}
*/
@SuppressWarnings("unchecked")
public static <T> T newInstanceIfPossible(Class<T> beanClass) {
Assert.notNull(beanClass);
public static <T> T newInstanceIfPossible(Class<T> type) {
Assert.notNull(type);
// 原始类型
if(type.isPrimitive()){
return (T) ClassUtil.getPrimitiveDefaultValue(type);
}
// 某些特殊接口的实例化按照默认实现进行
if (beanClass.isAssignableFrom(AbstractMap.class)) {
beanClass = (Class<T>) HashMap.class;
} else if (beanClass.isAssignableFrom(List.class)) {
beanClass = (Class<T>) ArrayList.class;
} else if (beanClass.isAssignableFrom(Set.class)) {
beanClass = (Class<T>) HashSet.class;
if (type.isAssignableFrom(AbstractMap.class)) {
type = (Class<T>) HashMap.class;
} else if (type.isAssignableFrom(List.class)) {
type = (Class<T>) ArrayList.class;
} else if (type.isAssignableFrom(Set.class)) {
type = (Class<T>) HashSet.class;
}
try {
return newInstance(beanClass);
return newInstance(type);
} catch (Exception e) {
// ignore
// 默认构造不存在的情况下查找其它构造
}
final Constructor<T>[] constructors = getConstructors(beanClass);
// 枚举
if (type.isEnum()) {
return type.getEnumConstants()[0];
}
// 数组
if (type.isArray()) {
return (T) Array.newInstance(type.getComponentType(), 0);
}
final Constructor<T>[] constructors = getConstructors(type);
Class<?>[] parameterTypes;
for (Constructor<T> constructor : constructors) {
parameterTypes = constructor.getParameterTypes();

View File

@ -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);
}
}