首页 > 解决方案 > 类型参数 T 扩展类不允许在方法中将类用作 T 参数

问题描述

所以我有这段代码:

public PacketListener packetListener;

@Override
protected void channelRead0(ChannelHandlerContext ctx, Packet<?> packet) throws Exception
{
    if (this.channel.isOpen()) {
        try {
            packet.handle(this.packetListener);
        }
        catch (Exception ex) {
            ;
        }
    }
}

packet.handle(this.packetListener);我得到错误The method handle(capture#1-of ?) in the type Packet<capture#1-of ?> is not applicable for the arguments (PacketListener):。这有什么问题?我的意思是我知道?类型是未知的,它通常不允许任何类型的参数(或者至少我已经读过),但是在代码中类型参数扩展PacketListener所以我看不到错误。

Packet 类如下所示:

public interface Packet<T extends PacketListener>
{
    void encode(PacketDataSerializer packetdataserializer) throws IOException;

    void decode(PacketDataSerializer packetdataserializer) throws IOException;

    void handle (T listener);
}

在假设任何事情之前,不,它与 Minecraft Server 无关,是的,我帮助自己使用了 Minecraft Server 源代码(来自 bukkit/spigot 服务器的那个)的命名和结构。

编辑:

好吧,评论让我思考,所以我测试了一些东西,它不是通配符,它​​不起作用......

private static <T extends PacketListener> void a(Packet<T> packet, PacketListener packetlistener) {
    packet.handle(packetlistener);
}

标签: javanetty

解决方案


让我们看一下这段代码:

private static <T extends PacketListener> void a(Packet<T> packet,
                                                 PacketListener packetlistener) {
    packet.handle(packetlistener);
}

这会调用类型为 的对象handle上的方法。该方法的签名在接口中定义为:packetPacket<T>Packet

    void handle (T listener);

所以它接受一个类型的参数Tpacketlistener但是您使用具有 type的参数调用它PacketListener。也就是说,参数的类型不是T,因为通常T可以是 的某个子类型PacketListener,但您只提供了基本类型PacketListener

最简单的解决方法是要求packetlistener对象具有 type T,因此它可以被handle方法接受:

private static <T extends PacketListener> void a(Packet<T> packet,
                           /* changed here -> */ T packetlistener) {
    packet.handle(packetlistener);
}

推荐阅读