Java实例化
我正在尝试创建一个新类,但我不完全确定该类的类型。我的代码可以更好地解释这一点:Java实例化,java,instantiation,instantiationexception,Java,Instantiation,Instantiationexception,我正在尝试创建一个新类,但我不完全确定该类的类型。我的代码可以更好地解释这一点: private static Class[] Packets = new Class[] { KeepAlivePacket.class, // 0x00 LoginRequestPacket.class, // 0x01 HandshakePacket.class, // 0x02
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;
}
}
如您所见,我试图实例化一个新对象,但我不能完全确定类类型是什么。然而,它却抛出了一个例外:
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)
对于这一点,反思是过分的 照办
switch (i) {
case 0: return new KeepAlivePacket();
case 1: return new LoginRequestPacket();
case 2: return new HandshakePacket();
default: throw new IllegalArgumentException();
}
理想情况下,用枚举替换i
这将使您获得静态类型和签名检查的优势,使您的代码更易于维护,并避免所有掩盖异常的反射废话。反射在这方面是过分的 照办
switch (i) {
case 0: return new KeepAlivePacket();
case 1: return new LoginRequestPacket();
case 2: return new HandshakePacket();
default: throw new IllegalArgumentException();
}
理想情况下,用枚举替换i
这将使您获得静态类型和签名检查的优势,使代码更易于维护,并避免所有掩盖异常的反射性废话。您正试图从静态方法中实例化非静态内部类。创建一个新的
HandshakePacket
对象需要一个周围的数据包对象作为其父对象,而您并没有提供它
因此,要么使
HandshakePacket
成为一个静态内部类,要么使getNewPacket
成为一个非静态方法,要么创建一个新的Packet对象作为新的HandshakePacket
对象的父对象。您试图从静态方法中实例化一个非静态内部类。创建一个新的HandshakePacket
对象需要一个周围的数据包对象作为其父对象,而您并没有提供它
因此,要么使
HandshakePacket
成为一个静态内部类,要么使getNewPacket
成为一个非静态方法,要么创建一个新的Packet对象作为新的HandshakePacket
对象的父对象。实例化异常包装了通常在它之后打印的真正异常。你能提供实际的例外情况吗?它还表示调用Packet.HandshakePacket的构造函数时发生异常。您能否提供导致异常的类的源代码,并告诉use它发生在哪一行?顺便问一下,setId
没有设置id
字段有什么原因吗?包括HandshakePacket
中与您的问题相关的代码,包括其构造函数。我建议复制/粘贴代码(不要在问题中手动键入)。@PeterLawrey我认为TCPPacket的内容是为了空间而隐藏的…@PeterLawrey我没有选择,这是从其他人的协议中获取数据包:/InstantiationException包装了真正的异常,通常在它之后打印。你能提供实际的例外情况吗?它还表示调用Packet.HandshakePacket的构造函数时发生异常。您能否提供导致异常的类的源代码,并告诉use它发生在哪一行?顺便问一下,setId
没有设置id
字段有什么原因吗?包括HandshakePacket
中与您的问题相关的代码,包括其构造函数。我建议复制/粘贴代码(不要在问题中手动输入)。@PeterLawrey我认为TCPPacket的内容是为了空间而隐藏的…@PeterLawrey我没有选择,这是从其他人的协议中获取数据包:/大约有200个数据包。这并不过分:/Meh,用代码换取内存是一个长期争论的问题。如果要从文件中读入配置,则可以更好地论证使用基于数据的分派而不是基于代码的分派。@Whitterer,对于大型手动编码阵列,交换机方法是成功的。密集int开关的每一个大小写开销为零,因为它只编译为一个边界检查和jsr
指令。返回无效构造函数调用结果的每个case语句对new
指令分别占用3个字节,返回1个字节。设置200个元素数组的静态初始值设定项的大小要大得多,因为每个aastore需要3条其他指令来设置堆栈:a=new Class[]{x,y,z}
实际上将desugas转换为a=new Class[3];a[0]=x;a[1]=y;a[2]=z代码>@voidWhisper,从运行时角度看,switch语句和CTOR可以通过JIT内联,但反射使用不会每次都产生运行时开销和不可预测的分支。大约有200个数据包。这并不过分:/Meh,用代码换取内存是一个长期争论的问题。如果要从文件中读入配置,则可以更好地论证使用基于数据的分派而不是基于代码的分派。@Whitterer,对于大型手动编码阵列,交换机方法是成功的。密集int开关的每一个大小写开销为零,因为它只编译为一个边界检查和jsr
指令。返回无效构造函数调用结果的每个case语句对new
指令分别占用3个字节,返回1个字节。设置200个元素数组的静态初始值设定项的大小要大得多,因为每个aastore需要3条其他指令来设置堆栈:a=new Class[]{x,y,z}
实际上将desugas转换为a=new Class[3];a[0]=x;a[1]=y;a[2]=z代码>@voidWhisper,从运行时角度来看,switch语句和ctor可以由JIT内联,但反射使用不会每次都产生运行时开销和不可预测的分支。@voidWhisper,如果要反射调用内部类构造函数,您需要将外部实例作为第一个参数传递,因为outerInstance.new NonStaticInnerClass()
desugas到new OuterClass$NonStaticInnerClass(outerInstance)
和new NonStaticInnerClass()
实际上是this.new NonStaticInnerClass()
所以desugas到new OuterClass$NonStaticInnerClass(这个)
Class.newInstance()
不起作用。您需要使用.Yo