diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/func/LambdaFactory.java b/hutool-core/src/main/java/org/dromara/hutool/core/func/LambdaFactory.java
index 6c1769892..139016b1e 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/func/LambdaFactory.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/func/LambdaFactory.java
@@ -82,52 +82,57 @@ public class LambdaFactory {
}
/**
- * 根据提供的方法或构造对象,构建对应的Lambda函数
+ * 根据提供的方法或构造对象,构建对应的Lambda函数,即通过Lambda函数代理方法或构造
* 调用函数相当于执行对应的方法或构造
*
- * @param funcType 接受Lambda的函数式接口类型
- * @param executable 方法对象,支持构造器
- * @param Function类型
+ * @param funcType 接受Lambda的函数式接口类型
+ * @param executable 方法对象,支持构造器
+ * @param Function类型
* @return 接受Lambda的函数式接口对象
*/
@SuppressWarnings("unchecked")
private static F doBuildWithoutCache(final Class funcType, final Executable executable) {
ReflectUtil.setAccessible(executable);
+ // 获取Lambda函数
+ final Method[] abstractMethods = MethodUtil.getPublicMethods(funcType, ModifierUtil::isAbstract);
+ Assert.equals(abstractMethods.length, 1, "不支持非函数式接口");
+
+ final Method invokeMethod = abstractMethods[0];
try {
- return (F) metaFactory(funcType, executable).getTarget().invoke();
+ return (F) metaFactory(funcType, invokeMethod, executable)
+ .getTarget().invoke();
} catch (final Throwable e) {
throw new HutoolException(e);
}
}
/**
- * 使用给定的函数接口,代理指定方法或构造
+ * 通过Lambda函数代理方法或构造
*
- * @param functionInterfaceType 函数接口
- * @param executable 方法或构造
- * @return 函数锚点
+ * @param funcType 函数类型
+ * @param invokeMethod 函数执行的方法
+ * @param executable 被代理的方法或构造
+ * @return {@link CallSite}
* @throws LambdaConversionException 权限等异常
*/
- private static CallSite metaFactory(final Class> functionInterfaceType, final Executable executable) throws LambdaConversionException {
- // 被代理的方法
- final Method[] abstractMethods = MethodUtil.getPublicMethods(functionInterfaceType, ModifierUtil::isAbstract);
- Assert.equals(abstractMethods.length, 1, "Class is not a functional interface.");
-
- final Method invokeMethod = abstractMethods[0];
- final MethodHandle methodHandle = LookupUtil.unreflect(executable);
- final MethodHandles.Lookup caller = LookupUtil.lookup();
+ private static CallSite metaFactory(final Class> funcType, final Method invokeMethod,
+ final Executable executable) throws LambdaConversionException {
+ final MethodHandles.Lookup caller = LookupUtil.lookup(executable.getDeclaringClass());
final String invokeName = invokeMethod.getName();
- final MethodType invokedType = MethodType.methodType(functionInterfaceType);
- final MethodType samMethodType = MethodType.methodType(invokeMethod.getReturnType(), invokeMethod.getParameterTypes());
+ final MethodType invokedType = MethodType.methodType(funcType);
- if(ClassUtil.isSerializable(functionInterfaceType)){
+ // 对入参做检查,原始类型转换为包装类型
+ final Class>[] paramTypes = invokeMethod.getParameterTypes();
+ final MethodType samMethodType = MethodType.methodType(invokeMethod.getReturnType(), paramTypes);
+
+ if (ClassUtil.isSerializable(funcType)) {
return LambdaMetafactory.altMetafactory(
caller,
invokeName,
invokedType,
samMethodType,
- methodHandle,
+ LookupUtil.unreflect(executable),
MethodTypeUtil.methodType(executable),
LambdaMetafactory.FLAG_SERIALIZABLE
);
@@ -138,7 +143,7 @@ public class LambdaFactory {
invokeName,
invokedType,
samMethodType,
- methodHandle,
+ LookupUtil.unreflect(executable),
MethodTypeUtil.methodType(executable)
);
}
diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/io/file/PathUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/io/file/PathUtilTest.java
index 3e33f7c89..6aefc7dbc 100644
--- a/hutool-core/src/test/java/org/dromara/hutool/core/io/file/PathUtilTest.java
+++ b/hutool-core/src/test/java/org/dromara/hutool/core/io/file/PathUtilTest.java
@@ -1,5 +1,6 @@
package org.dromara.hutool.core.io.file;
+import org.dromara.hutool.core.array.ArrayUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@@ -69,7 +70,13 @@ public class PathUtilTest {
@Test
public void getMimeOfRarTest(){
final String contentType = FileUtil.getMimeType("a001.rar");
- Assertions.assertEquals("application/x-rar-compressed", contentType);
+ Assertions.assertTrue(
+ ArrayUtil.contains(
+ new String[]{
+ "application/x-rar-compressed",
+ // JDK9+修改为此
+ "application/vnd.rar"},
+ contentType));
}
@Test
diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/lang/func/LambdaUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/lang/func/LambdaUtilTest.java
index b7ea25a06..daf27036e 100644
--- a/hutool-core/src/test/java/org/dromara/hutool/core/lang/func/LambdaUtilTest.java
+++ b/hutool-core/src/test/java/org/dromara/hutool/core/lang/func/LambdaUtilTest.java
@@ -180,6 +180,17 @@ public class LambdaUtilTest {
Assertions.assertTrue(bean.isFlag());
}
+ @Test
+ void buildSetterTest() {
+ final Bean bean = new Bean();
+ bean.setId(2L);
+ bean.setFlag(false);
+
+ final BiConsumer setter = LambdaUtil.buildSetter(Bean.class, "flag");
+ setter.accept(bean, true);
+ Assertions.assertTrue(bean.isFlag());
+ }
+
@SuppressWarnings("unchecked")
@Test
public void lambdaTest() {