簡體   English   中英

Java-實例化

[英]Java - Instantiation

我正在嘗試創建一個我不太確定類類型的東西的新類。 這可以用我的代碼更好地解釋:

private static Class[] Packets = new Class[]
            {
                KeepAlivePacket.class, // 0x00
                LoginRequestPacket.class, // 0x01
                HandshakePacket.class, // 0x02
                    }
.......

class HandshakePacket extends TCPPacket
{
    public HandshakePacket()
    {

    }
    byte protocolVersion;
    String username;
    String host;
    int port;
    @Override
    public void writePacketData(DataOutputStream os) throws IOException {
        os.write(id);
        os.writeByte(protocolVersion);
        writeString(os, username);
        writeString(os, host);
        os.writeInt(port);
    }
    @Override
    public void readPacketData(DataInputStream is) throws IOException {
        protocolVersion = is.readByte();
        username = readString(is,16);
        host = readString(is,16);
        port = is.readInt();
    }
    @Override
    public void setId(byte id)
    {
        this.id = id;
    }
}

.......
    public static TCPPacket getNewPacket(int i)
    {
    try
    {
        Class var1 = (Class)Packets[i];
        return var1 == null ? null : (TCPPacket)var1.newInstance(); <-- error on this line
    }
    catch (Exception var2)
    {
        var2.printStackTrace();
        System.out.println("Skipping packet with id " + i);
        return null;
    }
}

對於任何想知道TCPPacket是什么的人:

package vc.voidwhisperer.proxy.packet;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public class TCPPacket {
    public TCPPacket()
    {

    }
    public byte id = 0;
    public void writePacketData(DataOutputStream os) throws IOException
    {

    }
    public void readPacketData(DataInputStream is) throws IOException
    {

    }
    public void setId(byte id)
    {

    }
}

如您所見,我正在嘗試實例化一個我無法完全確定類類型是什么的新對象。 但是,它吐出了這個異常:

java.lang.InstantiationException: vc.voidwhisperer.proxy.packet.Packet$HandshakePacket
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at vc.voidwhisperer.proxy.packet.Packet.getNewPacket(Packet.java:2509)
at vc.voidwhisperer.proxy.UserConnection.run(UserConnection.java:52)

為此,反思是矯kill過正。

做就是了

switch (i) {
  case 0: return new KeepAlivePacket();
  case 1: return new LoginRequestPacket();
  case 2: return new HandshakePacket();
  default: throw new IllegalArgumentException();
}

並理想地用枚舉代替i

這將為您提供靜態類型和簽名檢查的優勢,使您的代碼更易於維護,並且避免了掩蓋異常的所有反射形式。

您正在嘗試從靜態方法中實例化非靜態內部類。 創建一個新的HandshakePacket對象需要一個環繞的Packet對象作為其父對象,而您沒有提供它。

因此,可以將HandshakePacket靜態內部類,或者將getNewPacket設置為非靜態方法,或者創建一個新的Packet對象以用作新的HandshakePacket對象的父級。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM