This commit is contained in:
Looly 2024-05-15 23:39:55 +08:00
parent aae583e57f
commit 5f1b010d08
2 changed files with 18 additions and 30 deletions

View File

@ -163,6 +163,7 @@ public class LookupUtil {
MethodHandle handle = null; MethodHandle handle = null;
final MethodHandles.Lookup lookup = LookupUtil.lookup(callerClass); final MethodHandles.Lookup lookup = LookupUtil.lookup(callerClass);
// 成员方法
try { try {
handle = lookup.findVirtual(callerClass, name, type); handle = lookup.findVirtual(callerClass, name, type);
} catch (final IllegalAccessException | NoSuchMethodException ignore) { } catch (final IllegalAccessException | NoSuchMethodException ignore) {

View File

@ -18,7 +18,6 @@ import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.reflect.lookup.LookupUtil; import org.dromara.hutool.core.reflect.lookup.LookupUtil;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method; import java.lang.reflect.Method;
/** /**
@ -42,6 +41,12 @@ public class MethodHandleUtil {
/** /**
* 执行方法句柄{@link MethodHandle#invokeWithArguments(Object...)}包装<br> * 执行方法句柄{@link MethodHandle#invokeWithArguments(Object...)}包装<br>
* 非static方法需先调用{@link MethodHandle#bindTo(Object)}绑定执行对象
*
* <p>
* 需要注意的是此处没有使用{@link MethodHandle#invoke(Object...)}因为其参数第一个必须为对象或类<br>
* {@link MethodHandle#invokeWithArguments(Object...)}只需传参数即可
* </p>
* *
* @param methodHandle {@link MethodHandle} * @param methodHandle {@link MethodHandle}
* @param args 方法参数值支持子类转换和自动拆装箱 * @param args 方法参数值支持子类转换和自动拆装箱
@ -72,14 +77,14 @@ public class MethodHandleUtil {
* MethodHandleUtil::invoke); * MethodHandleUtil::invoke);
* </pre> * </pre>
* *
* @param <T> 返回结果类型 * @param <T> 返回结果类型
* @param obj 接口的子对象或代理对象 * @param obj 接口的子对象或代理对象
* @param method 方法 * @param method 方法
* @param args 参数自动根据{@link Method}定义类型转换 * @param args 参数自动根据{@link Method}定义类型转换
* @return 结果 * @return 结果
* @throws HutoolException 执行异常包装 * @throws HutoolException 执行异常包装
*/ */
public static <T> T invoke(final Object obj, final Method method, final Object... args) throws HutoolException{ public static <T> T invoke(final Object obj, final Method method, final Object... args) throws HutoolException {
Assert.notNull(method, "Method must be not null!"); Assert.notNull(method, "Method must be not null!");
return invokeExact(obj, method, MethodUtil.actualArgs(method, args)); return invokeExact(obj, method, MethodUtil.actualArgs(method, args));
} }
@ -99,14 +104,14 @@ public class MethodHandleUtil {
* MethodHandleUtil::invoke); * MethodHandleUtil::invoke);
* </pre> * </pre>
* *
* @param <T> 返回结果类型 * @param <T> 返回结果类型
* @param obj 接口的子对象或代理对象 * @param obj 接口的子对象或代理对象
* @param method 方法 * @param method 方法
* @param args 参数 * @param args 参数
* @return 结果 * @return 结果
* @throws HutoolException 执行异常包装 * @throws HutoolException 执行异常包装
*/ */
public static <T> T invokeExact(final Object obj, final Method method, final Object... args) throws HutoolException{ public static <T> T invokeExact(final Object obj, final Method method, final Object... args) throws HutoolException {
Assert.notNull(method, "Method must be not null!"); Assert.notNull(method, "Method must be not null!");
MethodHandle handle; MethodHandle handle;
try { try {
@ -118,24 +123,6 @@ public class MethodHandleUtil {
if (null != obj) { if (null != obj) {
handle = handle.bindTo(obj); handle = handle.bindTo(obj);
} }
return invokeWithArguments(handle, args); return invokeHandle(handle, args);
}
/**
* 执行方法句柄{@link MethodHandle#invokeWithArguments(Object...)}包装<br>
*
* @param handle {@link MethodHandle}
* @param args 方法参数值支持子类转换和自动拆装箱
* @param <T> 返回值类型
* @return 方法返回值
*/
@SuppressWarnings("unchecked")
public static <T> T invokeWithArguments(final MethodHandle handle, final Object... args){
Assert.notNull(handle, "MethodHandle must be not null!");
try {
return (T) handle.invokeWithArguments(args);
} catch (final Throwable e) {
throw ExceptionUtil.wrapRuntime(e);
}
} }
} }