相关疑难解决方法(0)

我应该如何在我的用例中使用LambdaMetaFactory?

尽管已经阅读了我所知道的所有文档,但我无法解决使用lambdas执行方法的问题.为了给出一些背景知识,我的用例是一个插件系统.我正在使用一个可以分配给任何方法的注释(@EventHandle).我使用反射并遍历类中的每个方法并检查它是否具有注释,如果是,则将方法添加到处理程序对象(将其添加到列表以处理每个"tick").这是我的处理程序类:

package me.b3nw.dev.Events;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.lang.invoke.*;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

@Slf4j
public class Handler {

    @Getter
    private final Method method;
    @Getter
    private final EventHandle handle;
    private final MethodHandles.Lookup lookup;
    private final MethodHandle methodHandle;
    private final EventHandler invoker;

    public Handler(Method method, EventHandle handle) throws Throwable {
        this.method = method;

        log.info(method.getGenericReturnType() + "");

        for(Type type : method.getParameterTypes()) {
            log.info(type.getTypeName());
        }

        this.handle = handle;
        this.lookup = MethodHandles.lookup();
        this.methodHandle = lookup.unreflect(method);

        log.info("" + methodHandle.type().toMethodDescriptorString());

        this.invoker = (EventHandler) LambdaMetafactory.metafactory(lookup, "handle", MethodType.methodType(EventHandler.class), methodHandle.type(), …
Run Code Online (Sandbox Code Playgroud)

java reflection lambda java-8

5
推荐指数
1
解决办法
1017
查看次数

LambdaMetafactory 访问不同 ClassLoader 上的类

我有这段代码可以正常工作:

Method getterMethod = Person.class.getDeclaredMethod("getName");

MethodHandles.Lookup lookup = MethodHandles.publicLookup();
Class<?> declaringClass = getterMethod.getDeclaringClass();
Class<?> returnType = getterMethod.getReturnType();
CallSite getterSite = LambdaMetafactory.metafactory(lookup,
    "apply",
    MethodType.methodType(Function.class),
    MethodType.methodType(Object.class, Object.class),
    lookup.findVirtual(declaringClass, getterMethod.getName(), MethodType.methodType(returnType)),
    MethodType.methodType(propertyType, declaringClass));

Function getterFunction = (Function) getterSite.getTarget().invokeExact();
Run Code Online (Sandbox Code Playgroud)

但是,如果该getterMethod方法来自从不同 ClassLoader 加载的类,则会抛出:

Caused by: java.lang.invoke.LambdaConversionException: Invalid caller: java.lang.Object
    at java.lang.invoke.AbstractValidatingLambdaMetafactory.<init>(AbstractValidatingLambdaMetafactory.java:118)
    at java.lang.invoke.InnerClassLambdaMetafactory.<init>(InnerClassLambdaMetafactory.java:155)
    at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:299)
Run Code Online (Sandbox Code Playgroud)

如何将我的ClassLoader实例传递给LambdaMetafactory

java lambda methodhandle lambda-metafactory

5
推荐指数
1
解决办法
1669
查看次数