为什么我在 invokeExact 上得到 WrongMethodTypeException,即使 MethodHandle 没问题
Why do I get a WrongMethodTypeException on invokeExact even though MethodHandle is OK
我正在尝试调用一个调用方法,但出现了一个我无法解释的错误。
我听说 Invoke Exact 方法必须 return 但即使那样它也不起作用。
public boolean exec(String id, ChannelHandlerContext ctx, ByteBuf byteBuf) {
assert ctx != null;
assert byteBuf != null;
MethodHandle methodHandle = this.idMethods.get(id);
if(methodHandle != null) {
try {
Object object = this.idObjects.get(id);
Boolean b = (Boolean) methodHandle.invokeExact(object, ctx, byteBuf);
return true;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
return false;
}
在此代码上程序崩溃
Boolean b = (Boolean) methodHandle.invokeExact(object, ctx, byteBuf);
java.lang.invoke.WrongMethodTypeException: expected (,ChannelHandlerContext,ByteBuf)boolean but found (Object,ChannelHandlerContext,ByteBuf)Boolean
at java.lang.invoke.Invokers.newWrongMethodTypeException(Invokers.java:298)
at java.lang.invoke.Invokers.checkExactType(Invokers.java:309)
at de.moldiy.molnet.MessageExchangerManager.exec(MessageExchangerManager.java:54)
at de.moldiy.molnet.MessageHandler.channelRead0(MessageHandler.java:22)
at de.moldiy.molnet.MessageHandler.channelRead0(MessageHandler.java:7)
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:836)
这是包含我要调用的方法的class
s.loadMessageExchanger(new ServerMessageExchanger() {
@TrafficID(id = "cords")
public Boolean setCords(ChannelHandlerContext ctx,ByteBuf byteBuf) {
System.out.println("jaaa");
return true;
}
});
由于您是在 ServerMessageExchanger
的实例上调用方法,因此您需要将该实例作为第一个参数传递给 MethodHandle.invokeExact
。
像这样:
ServerMessageExchanger sme;
....
MethodHandle methodHandle = this.methods.get(id);
Boolean b = (Boolean) methodHandle.invokeExact(sme, ctx, byteBuf);
我现在知道出了什么问题,使用 invokeExact 你不能定义匿名 class 因为类型必须从一开始就知道,所以这是不可能的:
Object object = this.idObjects.get(id);
methodHandle.invokeExact(object, ctx, byteBuf);
但我只能使用 invoke:
Object object = this.idObjects.get(id);
methodHandle.invoke(object, ctx, byteBuf);
我正在尝试调用一个调用方法,但出现了一个我无法解释的错误。 我听说 Invoke Exact 方法必须 return 但即使那样它也不起作用。
public boolean exec(String id, ChannelHandlerContext ctx, ByteBuf byteBuf) {
assert ctx != null;
assert byteBuf != null;
MethodHandle methodHandle = this.idMethods.get(id);
if(methodHandle != null) {
try {
Object object = this.idObjects.get(id);
Boolean b = (Boolean) methodHandle.invokeExact(object, ctx, byteBuf);
return true;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
return false;
}
在此代码上程序崩溃
Boolean b = (Boolean) methodHandle.invokeExact(object, ctx, byteBuf);
java.lang.invoke.WrongMethodTypeException: expected (,ChannelHandlerContext,ByteBuf)boolean but found (Object,ChannelHandlerContext,ByteBuf)Boolean
at java.lang.invoke.Invokers.newWrongMethodTypeException(Invokers.java:298)
at java.lang.invoke.Invokers.checkExactType(Invokers.java:309)
at de.moldiy.molnet.MessageExchangerManager.exec(MessageExchangerManager.java:54)
at de.moldiy.molnet.MessageHandler.channelRead0(MessageHandler.java:22)
at de.moldiy.molnet.MessageHandler.channelRead0(MessageHandler.java:7)
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:836)
这是包含我要调用的方法的class
s.loadMessageExchanger(new ServerMessageExchanger() {
@TrafficID(id = "cords")
public Boolean setCords(ChannelHandlerContext ctx,ByteBuf byteBuf) {
System.out.println("jaaa");
return true;
}
});
由于您是在 ServerMessageExchanger
的实例上调用方法,因此您需要将该实例作为第一个参数传递给 MethodHandle.invokeExact
。
像这样:
ServerMessageExchanger sme;
....
MethodHandle methodHandle = this.methods.get(id);
Boolean b = (Boolean) methodHandle.invokeExact(sme, ctx, byteBuf);
我现在知道出了什么问题,使用 invokeExact 你不能定义匿名 class 因为类型必须从一开始就知道,所以这是不可能的:
Object object = this.idObjects.get(id);
methodHandle.invokeExact(object, ctx, byteBuf);
但我只能使用 invoke:
Object object = this.idObjects.get(id);
methodHandle.invoke(object, ctx, byteBuf);