diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java b/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java index 2f2dd4c6e..befac2469 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java @@ -1,10 +1,11 @@ package cn.hutool.core.lang.func; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.lang.Console; import cn.hutool.core.lang.SimpleCache; -import cn.hutool.core.text.CharPool; import cn.hutool.core.util.ClassUtil; import cn.hutool.core.util.ReflectUtil; +import cn.hutool.core.util.StrUtil; import java.io.Serializable; import java.lang.invoke.SerializedLambda; @@ -85,7 +86,7 @@ public class LambdaUtil { * @since 5.8.0 */ public static Class getImplClass(Func0 func) { - return ClassUtil.loadClass(resolve(func).getImplClass().replace(CharPool.SLASH, CharPool.DOT)); + return ClassUtil.loadClass(resolve(func).getImplClass()); } /** @@ -103,7 +104,36 @@ public class LambdaUtil { * @since 5.8.0 */ public static Class getImplClass(Func1 func) { - return ClassUtil.loadClass(resolve(func).getImplClass().replace(CharPool.SLASH, CharPool.DOT)); + return ClassUtil.loadClass(resolve(func).getImplClass()); + } + + /** + * 通过{@link SerializedLambda#getInstantiatedMethodType()}获取lambda实现类
+ * 在使用{@link #getImplClass(Func0)}获取实现类的时候,如果传入的是父类方法引用,会返回父类导致问题
+ * 此类通过方法的名称,截取出类名 + * + * @param func lambda + * @param

类型 + * @return lambda实现类 + */ + public static

Class

getInstantiatedClass(Func0 func) { + final String instantiatedMethodType = resolve(func).getInstantiatedMethodType(); + Console.log(instantiatedMethodType); + return ClassUtil.loadClass(StrUtil.sub(instantiatedMethodType, 2, StrUtil.indexOf(instantiatedMethodType, ';'))); + } + + /** + * 通过{@link SerializedLambda#getInstantiatedMethodType()}获取lambda实现类
+ * 在使用{@link #getImplClass(Func1)}获取实现类的时候,如果传入的是父类方法引用,会返回父类导致问题
+ * 此类通过方法的名称,截取出类名 + * + * @param func lambda + * @param

类型 + * @return lambda实现类 + */ + public static

Class

getInstantiatedClass(Func1 func) { + final String instantiatedMethodType = resolve(func).getInstantiatedMethodType(); + return ClassUtil.loadClass(StrUtil.sub(instantiatedMethodType, 2, StrUtil.indexOf(instantiatedMethodType, ';'))); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/util/ClassLoaderUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/ClassLoaderUtil.java index e2a901b8b..ef13c4f2e 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/ClassLoaderUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/ClassLoaderUtil.java @@ -5,6 +5,7 @@ import cn.hutool.core.exceptions.UtilException; import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.JarClassLoader; import cn.hutool.core.lang.SimpleCache; +import cn.hutool.core.text.CharPool; import java.io.File; import java.lang.reflect.Array; @@ -186,6 +187,9 @@ public class ClassLoaderUtil { public static Class loadClass(String name, ClassLoader classLoader, boolean isInitialized) throws UtilException { Assert.notNull(name, "Name must not be null"); + // 自动将包名中的"/"替换为"." + name = name.replace(CharPool.SLASH, CharPool.DOT); + // 加载原始类型和缓存中的类 Class clazz = loadPrimitiveClass(name); if (clazz == null) { 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 4d483fb08..a2bdec098 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 @@ -6,7 +6,11 @@ import cn.hutool.core.lang.func.LambdaUtil; import cn.hutool.core.map.MapUtil; import java.lang.reflect.Field; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.function.Function; /** @@ -234,9 +238,19 @@ public class EnumUtil { * @param 想要获取的字段类型 * @param 条件字段类型 * @return 对应枚举中另一字段值 ,获取不到时为 {@code null} + * @since 5.8.0 */ - public static , F, C> F getFieldBy(Function field, Func1 condition, C value) { - return Arrays.stream(LambdaUtil.getImplClass(condition).getEnumConstants()).filter(e -> condition.callWithRuntimeException(e).equals(value)).findAny().map(field).orElse(null); + public static , F, C> F getFieldBy(Func1 field, + Function condition, C value) { + Class implClass = LambdaUtil.getImplClass(field); + if(Enum.class.equals(implClass)){ + implClass = LambdaUtil.getInstantiatedClass(field); + } + return Arrays.stream(implClass.getEnumConstants()) + // 过滤 + .filter(e -> condition.apply(e).equals(value)) + // 获取第一个并转换为结果 + .findFirst().map(field::callWithRuntimeException).orElse(null); } /** diff --git a/hutool-core/src/test/java/cn/hutool/core/lang/func/LambdaUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/lang/func/LambdaUtilTest.java index 98075609c..316153fd3 100644 --- a/hutool-core/src/test/java/cn/hutool/core/lang/func/LambdaUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/lang/func/LambdaUtilTest.java @@ -36,6 +36,14 @@ public class LambdaUtilTest { Assert.assertEquals(MyTeacher.class, aClass); } + @Test + public void getInstantiatedClassTest() { + // 类方法引用,相当于获取的方法引用是:MyTeacher.getAge(this) + // 因此此处会匹配到Func1,其参数就是this + Class aClass = LambdaUtil.getInstantiatedClass(MyTeacher::getAge); + Assert.assertEquals(MyTeacher.class, aClass); + } + @Data static class MyTeacher { diff --git a/hutool-core/src/test/java/cn/hutool/core/util/EnumUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/EnumUtilTest.java index d95d2d963..aeeac4dc0 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/EnumUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/EnumUtilTest.java @@ -44,8 +44,11 @@ public class EnumUtilTest { @Test public void getFieldByTest() { // 枚举中字段互相映射使用 - String type = EnumUtil.getFieldBy(TestEnum::getType, TestEnum::ordinal, 1); + String type = EnumUtil.getFieldBy(TestEnum::getType, Enum::ordinal, 1); Assert.assertEquals("type2", type); + + int ordinal = EnumUtil.getFieldBy(TestEnum::ordinal, Enum::ordinal, 1); + Assert.assertEquals(1, ordinal); } @Test @@ -75,6 +78,7 @@ public class EnumUtilTest { } private final String type; + @SuppressWarnings("unused") private String name; public String getType() {