Java方法重载混乱

 学海无涯 发布于 2023-02-08 16:21

在服务器代码中,我有一个ProtocolHandler从套接字读取的类,找出它正在处理的数据包类型并将其分发给客户端.我正在尝试使用以下架构:

public interface Packet {
    //...
}

public class ClientInformations implements Packet {
    //...
}

public class ProtocolHandler {
    //....
    public void bytesReceived(byte[] bytes) {
        //... Determine the type of the packet
        Packet packet = determineTypeOfPacketAndRead(bytes);

        // Here  I already have the packet object built,
        // like ClientInformations@1a1a1a1a[...]

        client.packetReceived(packet);
    }
    //...
}

public class Client {
    //...
    public void packetReceived(Packet pkt) { 
        System.out.println("Unimplemented packet received.");
    }

    public void packetReceived(ClientInformations ci) {

    }

    //...
}

(我不知道如何用文字轻松解释).问题是,我真的以为packetReceived(ClientInformations)会被召唤,但事实并非如此.它称之为更通用的packetReceived(Packet)方法.我错了吗?那我怎么还能使用相同的架构呢?

- 编辑

现在我明白为什么会这样.问题是,我有其他分组类,例如Movement,Sync,Spawn.我想通过向类中添加新方法来轻松添加新数据包Client.那不是另一种方式吗?我的意思是,一种 在运行时自动分析packet对象类型并执行最具体方法调用的方法?

1 个回答
  • 我假设你有Packet packet = determineTYpeOfPacketAndRead(bytes),因为代码几乎没有其他方式可以编译.

    所以引用类型是Packet(在编译时),即使对象类型是ClientInformations(在运行时).

    并且在Java语言规范第15章中指定了方法重载.

    在编译时选择最具体的方法; 它的描述符确定在运行时实际执行的方法.

    更新:您的代码目前正常工作,因为您的代码中没有歧义,即使它没有按您希望的方式运行.但是,您将无法扩展此代码,因为它会导致问题,让我说明一下:

    我之前提出的建议如下:

    public class Client {
        //...
        public void unknownPacketReceived(Packet pkt) { 
            System.out.println("Unimplemented packet received.");
        }
    
        public void packetReceived(ClientInformations ci) {
    
        }
    
        //...
    }
    

    然而,这不能工作,因为ClientInformations对象是一个更复杂的东西作为一个简单的Packet对象/接口,它将给出以下编译错误:

    incompatible types: Packet cannot be converted to ClientInformations
    

    这种情况发生在引用类型仍然只有Packet,而你想把它提升为a ClientInformations.

    但是,如果您将其称为:

    client.receivedPacket((ClientInformations)packet)
    

    这在你的情况下没有坏处,因为在运行时它们是相同的类型,所以在转换中没有任何东西丢失,这需要伴随一instanceof棵树,这就是你现在回到零步的原因.

    这个程序不只是起作用,如果你希望它变得简单,我建议改变你的设计,如果你正在研究一个遗留应用程序并且不能改变一些东西,那么继续这条路可能是一个选择,但它赢得了'很容易.

    2023-02-08 16:23 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有