在服务器代码中,我有一个 ProtocolHandler
类,它从套接字读取数据,找出它正在处理的数据包类型并将其分派(dispatch)给客户端。我正在尝试拥有以下架构:
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
对象的类型并进行最具体的方法调用吗?
最佳答案
我假设您有 Packet packet = determineTYpeOfPacketAndRead(bytes)
,因为几乎没有其他方法可以编译代码。
所以 reference 类型是 Packet
(在编译时),即使 object 类型是 ClientInformations
(在运行时)。
并且如 Java 语言规范第 15 章所述方法重载。
The most specific method is chosen at compile-time; its descriptor determines what method is actually executed at run-time.
更新:您的代码目前可以正常工作,因为您的代码没有歧义,即使它的行为不符合您的要求。但是,您将无法扩展此代码,因为它会导致问题,让我举例说明:
我之前的一个建议如下:
public class Client {
//...
public void unknownPacketReceived(Packet pkt) {
System.out.println("Unimplemented packet received.");
}
public void packetReceived(ClientInformations ci) {
}
//...
}
然而,这不能像 ClientInformations
对象一样工作,因为它是一个更复杂的简单 Packet
对象/接口(interface),它会给出以下编译错误:
incompatible types: Packet cannot be converted to ClientInformations
发生这种情况是因为 reference 类型仍然只是 Packet
,而您希望将其提升为 ClientInformations
。
它可以工作,但是如果你将它命名为:
client.receivedPacket((ClientInformations)packet)
这对你的情况没有坏处,因为在运行时它们是相同的类型,所以在转换中不会丢失任何东西,这需要伴随着 instanceof
树,这就是为什么你现在回到了零步。
这个程序只是会起作用,如果你想让它简单,我建议改变你的设计,继续这条路可能是一个选择,如果您正在处理遗留应用程序,不能只是更改内容,但这并不容易。
关于Java方法重载困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20732451/