Java Class.cast()和重载
我正在尝试为一个小服务器编写数据包监听器.我是
Java的新手,这是我第一次搞乱网络.整个想法是重新接收数据包,将数据包id与它的类匹配,将输入流传递给数据包的构造函数,以便可以构造它然后将其提供给packetHander,它将为每个数据包提供重叠方法.要使用将数据包ID映射到每个类的数组,并使用一个名为decode的方法来构造数据包,来实现这个im.问题是handlePacket的重载它没有按预期运行.让我们看一些代码.
我在一个线程中运行数据包监听器,run方法如下所示: public void run() { try { int packet_id; while ((packet_id = istream.readInt()) != -1) { plugin.getServer().getConsoleSender().sendMessage("[Comm] Recived packet " + packet_id); Packet packet = decode(packet_id,istream); plugin.getServer().getConsoleSender().sendMessage("[Comm] Packet is " + Class.forName(packet.getClass().getName())); plugin.getServer().getConsoleSender().sendMessage("[Comm] Class is " + Packet00ReqIdentify.class.cast(packet).getClass().getName()); plugin.getServer().getConsoleSender().sendMessage("[Comm] Class is " + Class.forName(packet.getClass().getName()).getName()); handlePacket(packet); } } catch (IOException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | ClassNotFoundException e) { e.printStackTrace(); } } decode和handlePacket方法如下所示: private void handlePacket(Packet00ReqIdentify packet) throws IOException { plugin.getServer().getConsoleSender().sendMessage("[Comm] Got it!"); } private void handlePacket(Packet packet) { plugin.getServer().getConsoleSender().sendMessage("[Comm] Woops!"); } private Packet decode(int packet_id,PacketInputStream istream) throws NoSuchMethodException,SecurityException,InstantiationException,IllegalAccessException,IllegalArgumentException,InvocationTargetException,ClassNotFoundException,IOException { Class<? extends Packet> packet_class = packets_ids.get(packet_id); try { Constructor<?> packet_constructor = packet_class.getConstructor(PacketInputStream.class); return Class.forName(packet_class.getName()).asSubclass(Packet.class).cast(packet_constructor.newInstance(istream)); } catch (NoSuchMethodException e) { return Class.forName(packet_class.getName()).asSubclass(Packet.class).cast(packet_class.newInstance()); } } packets_ids它是一个数组,包含对每个数据包类的引用,由他们的id索引: private static ArrayList<Class<? extends Packet>> packets_ids; 它以这种方式初始化: private static void registerPacket(int id,Class<? extends Packet> oclass) { packets_ids.add(id,oclass); } static { packets_ids = new ArrayList<Class<? extends Packet>>(); registerPacket(Packet00ReqIdentify.assigned_pid,Packet00ReqIdentify.class); registerPacket(Packet01Identify.assigned_pid,Packet01Identify.class); registerPacket(Packet02Heartbeat.assigned_pid,Packet02Heartbeat.class); } 如果我执行此操作并测试它发送类型为00的数据包,我得到这个: 17:37:49 [INFO] [Comm] Connection established to localhost:11000 17:37:49 [INFO] [Comm] Recived packet 0 17:37:49 [INFO] [Comm] Packet is class com.gamerarg.commclient.protocol.Packet00ReqIdentify 17:37:49 [INFO] [Comm] Class is com.gamerarg.commclient.protocol.Packet00ReqIdentify 17:37:49 [INFO] [Comm] Class is com.gamerarg.commclient.protocol.Packet00ReqIdentify 17:37:49 [INFO] [Comm] Woops! 所以这意味着packet00还没有被“handlePacket(Packet00ReqIdentify packet)”所捕获.如果我在handlePacket调用中对“packet”进行显式转换,则它可以工作.所以问题是: >为什么这不起作用?当我打印两个类名时,我得到相同的. 谢谢! 解决方法
在每个Packet子类中,实现一个方法public void handle(),它执行处理数据包所需的操作.或
>在Packet中放置handle()的默认实现,或 然后更换 handlePacket(packet); 同 packet.handle(); 这是行动中的多态性.它将在运行时工作,检查数据包引用的对象的类,并调用正确的handle方法版本. 如果handle()需要访问原始的PacketListener,则将其声明为public void handle(PacketListener listener)并将其称为packet.handle(this); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |