首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java实例化

Java实例化
EN

Stack Overflow用户
提问于 2012-12-29 01:04:37
回答 2查看 2.5K关注 0票数 0

我正在尝试创建一个新类,其中包含一些我不完全确定类类型的内容。这可以用我的代码更好地解释:

代码语言:javascript
运行
复制
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是什么的人:

代码语言:javascript
运行
复制
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)
    {

    }
}

如你所见,我正在尝试实例化一个新的对象,我不能完全确定类的类型是什么。然而,它却抛出了这个异常:

代码语言:javascript
运行
复制
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)
EN

回答 2

Stack Overflow用户

发布于 2012-12-29 01:14:40

对于这一点,反射是过度杀伤力。

只管去做

代码语言:javascript
运行
复制
switch (i) {
  case 0: return new KeepAlivePacket();
  case 1: return new LoginRequestPacket();
  case 2: return new HandshakePacket();
  default: throw new IllegalArgumentException();
}

理想情况下,用枚举替换i

这将使您获得静态类型和签名检查的优势,使您的代码更易于维护,并避免所有掩盖异常的反射废话。

票数 2
EN

Stack Overflow用户

发布于 2012-12-29 01:46:11

您正在尝试从静态方法中实例化一个非静态内部类。创建新的HandshakePacket对象需要一个周围的Packet对象作为它的父对象,而您没有提供这样的对象。

因此,要么使HandshakePacket成为一个静态内部类,使getNewPacket成为一个非静态方法,要么创建一个新Packet对象作为新HandshakePacket对象的父对象。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14073034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档