0

クラスの種類がよくわからない新しいクラスを作成しようとしています。これは私のコードでよりよく説明できます:

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)
4

2 に答える 2

2

これにはリフレクションはやり過ぎです。

やるだけ

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

理想的にiは列挙型に置き換えます。

これにより、静的な型と署名チェックの利点が得られ、コードがより保守しやすくなり、例外をマスクするすべての反射ガフが回避されます。

于 2012-12-28T17:14:40.227 に答える
2

静的メソッド内から非静的内部クラスをインスタンス化しようとしています。新しいHandshakePacketオブジェクトを作成するには、親として周囲の Packet オブジェクトが必要ですが、提供していません。

したがって、HandshakePacket静的内部クラスを作成getNewPacketするか、非静的メソッドを作成するか、新しいオブジェクトの親として使用する新しい Packet オブジェクトを作成しHandshakePacketます。

于 2012-12-28T17:46:11.030 に答える