可以在Java中使用类似结构的构造吗?

可以在Java中使用类似结构的构造吗?,java,struct,Java,Struct,我正在考虑在一个大型项目中使用Java,但我还没有找到任何可以在Java中远程表示结构的东西。我需要能够将网络数据包转换为可在应用程序中使用的结构/类 我知道可以使用RandomAccessFile,但这种方式是不可接受的。所以我很好奇,是否有可能像我在C中所做的那样,将一组字节“强制转换”为一个结构。如果这不可能,那么我就不能使用Java 因此,我要问的问题是,除了指定对齐方式和数据类型之外,是否可以将对齐的数据强制转换到类,而无需额外的努力?没有与您的描述匹配的内容 在Java中,最接近结构

我正在考虑在一个大型项目中使用Java,但我还没有找到任何可以在Java中远程表示结构的东西。我需要能够将网络数据包转换为可在应用程序中使用的结构/类

我知道可以使用
RandomAccessFile
,但这种方式是不可接受的。所以我很好奇,是否有可能像我在C中所做的那样,将一组字节“强制转换”为一个结构。如果这不可能,那么我就不能使用Java


因此,我要问的问题是,除了指定对齐方式和数据类型之外,是否可以将对齐的数据强制转换到类,而无需额外的努力?

没有与您的描述匹配的内容

在Java中,最接近结构的是一个简单的类,它保存的值可以通过其字段或set/get方法访问


在Java类实例和在线表示之间转换的典型方法是Java序列化,可以根据需要进行大量定制。它是Java的远程方法调用API使用的,工作非常好。

否。您不能将字节数组强制转换为类对象

也就是说,您可以使用一个函数,轻松地将所需字段提取到如下对象:

class Packet {

    private final int type;
    private final float data1;
    private final short data2;

    public Packet(byte[] bytes) {
        ByteBuffer bb = ByteBuffer.wrap(bytes);
        bb.order(ByteOrder.BIG_ENDIAN); // or LITTLE_ENDIAN

        type = bb.getInt();
        data1 = bb.getFloat();
        data2 = bb.getShort();
    }
}

你基本上是在问你是否可以用C语言解决另一种语言的问题。不出所料,答案是“不”

但是,完全可以构造一个类,该类在其构造函数中接受一组字节并构造一个适当的实例

class Foo {

  int someField;
  String anotherField;

  public Foo(byte[] bytes) {
    someField = someFieldFromBytes(bytes);
    anotherField = anotherFieldFromBytes(bytes);
    etc.
 }
}

您可以确保类实例与字节数组之间存在一对一的映射。添加toBytes()方法将实例序列化为字节。

不,您不能这样做。Java与C没有相同的概念

您可以创建一个行为类似于结构的类:

public class Structure {
    public int field1;
    public String field2;
}
您可以使用一个构造函数来读取数组或字节,或者使用
DataInput
来读取字节:

public class Structure {
    ...
    public Structure(byte[] data) {
        this(new DataInputStream(new ByteArrayInputStream(data)));
    }

    public Structure(DataInput in) {
        field1 = in.readInt();
        field2 = in.readUTF();
    }
}
然后从线路上读取字节,并将它们注入结构中:

byte[] bytes = network.read();
DataInputStream stream = new DataInputStream(new ByteArrayInputStream(bytes));
Structure structure1 = new Structure(stream);
Structure structure2 = new Structure(stream);
...

它不像C语言那么简洁,但它非常接近。请注意,
DataInput
接口可以干净地代表您消除任何与endianness有关的混乱,因此这绝对是C语言的优势。

正如Joshua所说,序列化是完成这类事情的典型方式。但是,您还可以使用其他二进制协议,如MessagePack、ProtocolBuffers和AvRO


如果您想使用字节码结构,请查看ASM和CGLIB;这些在Java应用程序中非常常见。

不,这是不可能的。您正在尝试使用类似Java的C语言,这必然会导致复杂性。要么学习用Java的方式做事,要么回到C


在这种情况下,Java方式可能涉及和/或。

您不能将字节数组强制转换为类的实例。 但是您可以用java做更多的事情。 Java具有内部的、非常强大且非常灵活的序列化机制。这就是你需要的。您可以在流中读写对象


如果双方都是用java编写的,那么根本就没有问题。如果其中一方不是java,则可以自定义序列化。从读取java.util.Serializable的javadoc开始

大多数Java开发人员使用什么将字节强制转换为类?我认为您是在询问一个类的实例。在这种情况下,您可以使用ObjectInputStream。您从不向类强制转换字节。但您可以以特定于实现的方式将字节映射到类。这就是@Joshua Kaplan在他的回答中所指的。请注意,您必须小心编码,而且Java比C强得多,所以uint16\u t、size\u t等东西不会映射到其他地方。根据Josh Block的有效Java第三版,Java的序列化被认为是危险的,不应该在任何新项目中使用
ByteBuffer.wrap(new byte[] {}).getDouble();