【问题标题】:Why a WrongMethodTypeException from MethodHandle? Is my object type incorrect?为什么来自 MethodHandle 的 WrongMethodTypeException?我的对象类型不正确吗?
【发布时间】:2022-12-17 16:40:29
【问题描述】:

我在尝试将我的事件系统从反射切换到 MethodHandle 时遇到了问题。

我在 Github (https://github.com/KyoriPowered/event) 上使用 KyoriPowered 的事件总线(版本 3.0.0)。

我的代码如下:

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
            }
        }
    }
}

我希望这能正常工作,但结果是:

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

UserOnlineEvent 是测试中使用的事件类型。

问题是我无法获得事件的真实类型。

【问题讨论】:

  • 那是整个异常消息吗? MethodHandle(,UserOnlineEvent) 中的逗号之前似乎应该有其他类型,返回类型也丢失了。
  • 您是否正在尝试调用静态方法?如果不是,则 MethodHandle 将有 2 个参数。
  • @JornVernee 哦,对不起,返回类型是无效的,我已经编辑了它。我不知道逗号的含义,整个异常消息就在这里。
  • @JohannesKuhn 当然不是,我稍后会尝试。

标签: java reflection methodhandle


【解决方案1】:

根据你的消息,我在JDK中找到了代码。在MethodHandle#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);
    }

很明显,我猜参数类型是错误的。如果调试,你会找到它。

【讨论】:

  • 我确定 UserOnlineEvent 是事件的子类。但是我怎么投呢?实际类型在代码中是未知且不可访问的。
猜你喜欢
  • 2021-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-26
  • 1970-01-01
  • 2010-12-11
  • 2023-04-06
相关资源
最近更新 更多