简体   繁体   English

为什么来自 MethodHandle 的 WrongMethodTypeException? 我的 object 类型不正确吗?

[英]Why a WrongMethodTypeException from MethodHandle? Is my object type incorrect?

I have encountered a problem while I am trying to switch my event system from reflection to MethodHandle.我在尝试将我的事件系统从反射切换到 MethodHandle 时遇到了问题。

I am using an event bus (version 3.0.0) by KyoriPowered on Github ( https://github.com/KyoriPowered/event ).我正在使用 KyoriPowered 在 Github ( https://github.com/KyoriPowered/event ) 上的事件总线(版本 3.0.0)。

My code is following:我的代码如下:

public class EventExecutorFactory implements EventExecutor.Factory<Event, Listener> {
    @Override
    public @NonNull EventExecutor<Event, Listener> create(@NonNull Object object, @NonNull Method method) throws Exception { // object is Listener
        method.setAccessible(true);
        Class<? extends Event> actualEventType = method.getParameterTypes()[0].asSubclass(Event.class);
        MethodHandle handle = MethodHandles.lookup().unreflect(method);
        return new EventExecutor<Event,Listener>() {

            @Override
            public void invoke(@NonNull Listener listener, @NonNull Event event) throws Throwable {
                if (!actualEventType.isInstance(event)) return; // many different event types defined in my system, so I should check it first.
                handle.invoke(actualEventType.cast(event)); // WrongMethodTypeException thrown here
            }
        }
    }
}

I expected this to work fine, but the result is:我希望这能正常工作,但结果是:

java.lang.invoke.WrongMethodTypeException: cannot convert MethodHandle(,UserOnlineEvent)void to (Event)void java.lang.invoke.WrongMethodTypeException:无法将 MethodHandle(,UserOnlineEvent)void 转换为 (Event)void

UserOnlineEvent is the event type that used in test. UserOnlineEvent 是测试中使用的事件类型。

The problem is that I cannot get the real type of the event.问题是我无法获得事件的真实类型。


Edit: This problem has been solved.编辑:这个问题已经解决。 I should use two arguments. just add the listener as the first argument to handle.invoke, and it works.我应该使用两个 arguments。只需将侦听器添加为 handle.invoke 的第一个参数,它就可以工作。

According to your message, I find the code in JDK.根据你的消息,我在JDK中找到了代码。 at MethodHandle#asTypeUncachedMethodHandle#asTypeUncached

/*non-public*/ 
MethodHandle asTypeUncached(MethodType newType) {
        if (!type.isConvertibleTo(newType))
            throw new WrongMethodTypeException("cannot convert "+this+" to "+newType);
        return asTypeCache = MethodHandleImpl.makePairwiseConvert(this, newType, true);
    }

it's clear, I guess parameter type is wrong.很明显,我猜参数类型是错误的。 if debug, you will find it.如果调试,你会发现它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM