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

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

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

所以我问的问题是,除了指定对齐和数据类型之外,是否可以将对齐的数据转换为类而无需任何额外的工作?

您基本上是在询问是否可以使用特定于C的解决方案来解决另一种语言的问题。 可以预见,答案是’不’。

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

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

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

不可以。您不能将一个字节数组转换为类对象。

话虽这么说,你可以使用java.nio.Buffer并轻松地提取你需要的字段,如下所示:

 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(); } } 

不,你做不到。 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(); } } 

然后从线上读取字节并将它们泵入Structures

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

它不像C那样简洁,但它非常接近。 请注意, DataInput接口会代表您干净地删除任何带有字节序的乱码,因此这绝对比C更有利。

没有什么能与您的描述相符。

与Java中的结构最接近的是一个简单的类,它通过它的字段或set / get方法保存值。

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

正如约书亚所说,序列化是做这些事情的典型方式。 但是,您还有其他二进制协议,如MessagePack,ProtocolBuffers和AvRO。

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

 ByteBuffer.wrap(new byte[] {}).getDouble(); 

不,这是不可能的。 你正试图像C一样使用Java,这必然会引起并发症。 要么学会用Java方式做事,要么回到C.

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

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

如果双方都是用java编写的,那就完全没问题了。 如果其中一方不是java,您可以自定义序列化。 从阅读java.util.Serializable的javadoc开始。