Итак, у меня есть немного кода:

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);
}
3
Martin McNamee 24 Ноя 2019 в 01:00

1 ответ

Лучший ответ

Взглянем на этот код:

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

Это вызывает метод handle объекта packet, который имеет тип Packet<T>. Подпись этого метода определяется в интерфейсе Packet следующим образом:

    void handle (T listener);

Так что он принимает параметр типа T. Но вы вызываете его с аргументом packetlistener, который имеет тип PacketListener. То есть тип аргумента не T, поскольку в общем случае T может быть некоторым подтипом PacketListener, но вы указали только базовый тип PacketListener.

Самое простое исправление состоит в том, что объект packetlistener должен иметь тип T, поэтому он может быть принят методом handle:

private static <T extends PacketListener> void a(Packet<T> packet,
                           /* changed here -> */ T packetlistener) {
    packet.handle(packetlistener);
}
2
kaya3 24 Ноя 2019 в 01:58