diff --git a/CHANGELOG.md b/CHANGELOG.md index a8279ec54..8f4ca5c2a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.28(2024-05-09) +# 5.8.28(2024-05-10) ### 🐣新特性 * 【core 】 修正XmlUtil的omitXmlDeclaration描述注释(issue#I9CPC7@Gitee) @@ -34,6 +34,7 @@ * 【core 】 修复ZipReader.checkZipBomb遇到空目录报错问题(issue#I9K494@Gitee) * 【db 】 修复Oracle下特殊表名导致meta信息获取不到问题(issue#I9BANE@Gitee) * 【db 】 修复FuncComparator.thenComparing不生效问题(issue#3569@Github) +* 【core 】 修复EnumUtil空指针问题(issue#I9NSZ4@Gitee) ------------------------------------------------------------------------------------------------------------- # 5.8.27(2024-03-29) diff --git a/hutool-core/src/main/java/cn/hutool/core/util/EnumUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/EnumUtil.java index fb9fdf23d..3036cd762 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/EnumUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/EnumUtil.java @@ -1,16 +1,13 @@ package cn.hutool.core.util; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.func.Func1; import cn.hutool.core.lang.func.LambdaUtil; import cn.hutool.core.map.MapUtil; import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.function.Function; import java.util.function.Predicate; @@ -29,8 +26,7 @@ public class EnumUtil { * @return 是否为Enum类 */ public static boolean isEnum(Class clazz) { - Assert.notNull(clazz); - return clazz.isEnum(); + return Assert.notNull(clazz).isEnum(); } /** @@ -40,8 +36,7 @@ public class EnumUtil { * @return 是否为Enum类 */ public static boolean isEnum(Object obj) { - Assert.notNull(obj); - return obj.getClass().isEnum(); + return Assert.notNull(obj).getClass().isEnum(); } /** @@ -65,7 +60,14 @@ public class EnumUtil { * @since 5.1.6 */ public static > E getEnumAt(Class enumClass, int index) { + if(null == enumClass){ + return null; + } final E[] enumConstants = enumClass.getEnumConstants(); + if(index < 0){ + index = enumConstants.length + index; + } + return index >= 0 && index < enumConstants.length ? enumConstants[index] : null; } @@ -79,6 +81,9 @@ public class EnumUtil { * @since 4.1.13 */ public static > E fromString(Class enumClass, String value) { + if (null == enumClass || StrUtil.isBlank(value)) { + return null; + } return Enum.valueOf(enumClass, value); } @@ -107,10 +112,6 @@ public class EnumUtil { * @since 4.5.18 */ public static > E fromStringQuietly(Class enumClass, String value) { - if (null == enumClass || StrUtil.isBlank(value)) { - return null; - } - try { return fromString(enumClass, value); } catch (IllegalArgumentException e) { @@ -128,6 +129,9 @@ public class EnumUtil { */ @SuppressWarnings("unchecked") public static > E likeValueOf(Class enumClass, Object value) { + if(null == enumClass || null == value){ + return null; + } if (value instanceof CharSequence) { value = value.toString().trim(); } @@ -157,6 +161,9 @@ public class EnumUtil { * @return name列表 */ public static List getNames(Class> clazz) { + if(null == clazz){ + return null; + } final Enum[] enums = clazz.getEnumConstants(); if (null == enums) { return null; @@ -176,6 +183,9 @@ public class EnumUtil { * @return 字段值列表 */ public static List getFieldValues(Class> clazz, String fieldName) { + if(null == clazz || StrUtil.isBlank(fieldName)){ + return null; + } final Enum[] enums = clazz.getEnumConstants(); if (null == enums) { return null; @@ -200,6 +210,9 @@ public class EnumUtil { * @since 4.1.20 */ public static List getFieldNames(Class> clazz) { + if(null == clazz){ + return null; + } final List names = new ArrayList<>(); final Field[] fields = ReflectUtil.getFields(clazz); String name; @@ -225,25 +238,31 @@ public class EnumUtil { * @since 5.8.0 */ public static > E getBy(Class enumClass, Predicate predicate) { + if(null == enumClass || null == predicate){ + return null; + } return Arrays.stream(enumClass.getEnumConstants()) - .filter(predicate).findFirst().orElse(null); + .filter(predicate).findFirst().orElse(null); } /** * 通过 某字段对应值 获取 枚举,获取不到时为 {@code null} * - * @param condition 条件字段 + * @param condition 条件字段,为{@code null}返回{@code null} * @param value 条件字段值 * @param 枚举类型 * @param 字段类型 * @return 对应枚举 ,获取不到时为 {@code null} */ public static , C> E getBy(Func1 condition, C value) { - Class implClass = LambdaUtil.getRealClass(condition); - if (Enum.class.equals(implClass)) { - implClass = LambdaUtil.getRealClass(condition); + if (null == condition) { + return null; } - return Arrays.stream(implClass.getEnumConstants()).filter(e -> condition.callWithRuntimeException(e).equals(value)).findAny().orElse(null); + final Class implClass = LambdaUtil.getRealClass(condition); + return Arrays.stream(implClass.getEnumConstants()) + .filter(constant -> ObjUtil.equals(condition.callWithRuntimeException(constant), value)) + .findAny() + .orElse(null); } /** @@ -264,8 +283,8 @@ public class EnumUtil { /** * 通过 某字段对应值 获取 枚举中另一字段值,获取不到时为 {@code null} * - * @param field 你想要获取的字段 - * @param condition 条件字段 + * @param field 你想要获取的字段,{@code null}返回{@code null} + * @param condition 条件字段,{@code null}返回{@code null} * @param value 条件字段值 * @param 枚举类型 * @param 想要获取的字段类型 @@ -273,17 +292,18 @@ public class EnumUtil { * @return 对应枚举中另一字段值 ,获取不到时为 {@code null} * @since 5.8.0 */ - public static , F, C> F getFieldBy(Func1 field, - Function condition, C value) { - Class implClass = LambdaUtil.getRealClass(field); - if (Enum.class.equals(implClass)) { - implClass = LambdaUtil.getRealClass(field); + public static , F, C> F getFieldBy(Func1 field, Function condition, C value) { + if(null == field || null == condition){ + return null; } + final Class implClass = LambdaUtil.getRealClass(field); return Arrays.stream(implClass.getEnumConstants()) - // 过滤 - .filter(e -> condition.apply(e).equals(value)) - // 获取第一个并转换为结果 - .findFirst().map(field::callWithRuntimeException).orElse(null); + // 过滤 + .filter(constant -> ObjUtil.equals(condition.apply(constant), value)) + // 获取第一个并转换为结果 + .findFirst() + .map(field::callWithRuntimeException) + .orElse(null); } /** @@ -296,6 +316,9 @@ public class EnumUtil { * @since 4.0.2 */ public static > LinkedHashMap getEnumMap(final Class enumClass) { + if(null == enumClass){ + return null; + } final LinkedHashMap map = new LinkedHashMap<>(); for (final E e : enumClass.getEnumConstants()) { map.put(e.name(), e); @@ -312,6 +335,9 @@ public class EnumUtil { * @return 枚举名对应指定字段值的Map */ public static Map getNameFieldMap(Class> clazz, String fieldName) { + if(null == clazz || StrUtil.isBlank(fieldName)){ + return null; + } final Enum[] enums = clazz.getEnumConstants(); if (null == enums) { return null; @@ -332,7 +358,11 @@ public class EnumUtil { * @return 是否存在 */ public static > boolean contains(final Class enumClass, String val) { - return EnumUtil.getEnumMap(enumClass).containsKey(val); + final LinkedHashMap enumMap = getEnumMap(enumClass); + if(CollUtil.isEmpty(enumMap)){ + return false; + } + return enumMap.containsKey(val); } /** diff --git a/hutool-core/src/test/java/cn/hutool/core/util/IssueI9NSZ4Test.java b/hutool-core/src/test/java/cn/hutool/core/util/IssueI9NSZ4Test.java new file mode 100644 index 000000000..763bfd96a --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/util/IssueI9NSZ4Test.java @@ -0,0 +1,90 @@ +package cn.hutool.core.util; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; +import org.junit.Assert; +import org.junit.Test; + +public class IssueI9NSZ4Test { + + @Test + public void getByTest() { + // AnimalKindInZoo所有枚举结果的getMappedValue结果值中都无AnimalKind.DOG,返回null + final AnimalKindInZoo by = EnumUtil.getBy(AnimalKindInZoo::getMappedValue, AnimalKind.DOG); + Assert.assertNull(by); + } + + @Test + public void getByTest2() { + // AnimalKindInZoo所有枚举结果的getMappedValue结果值中都无AnimalKind.DOG,返回null + final AnimalKindInZoo by = EnumUtil.getBy(AnimalKindInZoo::getMappedValue, AnimalKind.BIRD); + Assert.assertEquals(AnimalKindInZoo.BIRD, by); + } + + /** + * 动物类型 + */ + @Getter + @ToString + @AllArgsConstructor + public enum AnimalKind { + + /** + * 猫 + */ + CAT("cat", "猫"), + /** + * 狗 + */ + DOG("dog", "狗"), + /** + * 鸟 + */ + BIRD("bird", "鸟"); + + /** + * 键 + */ + private final String key; + /** + * 值 + */ + private final String value; + } + + /** + * 动物园里的动物类型 + */ + @Getter + @ToString + @AllArgsConstructor + public enum AnimalKindInZoo { + + /** + * 猫 + */ + CAT("cat", "猫", AnimalKind.CAT), + /** + * 蛇 + */ + SNAKE("snake", "蛇", null), + /** + * 鸟 + */ + BIRD("bird", "鸟", AnimalKind.BIRD); + + /** + * 键 + */ + private final String key; + /** + * 值 + */ + private final String value; + /** + * 映射值 + */ + private final AnimalKind mappedValue; + } +}