Bootstrap

Java中如何实现结构体

1.引言

Javolution 是一个开源的 Java 库,旨在支持高性能计算 (HPC) 和科学应用。它提供了一系列工具和算法,帮助开发者优化他们的应用程序性能,尤其是在并行处理、内存管理以及数学运算方面。Javolution 特别适合那些对计算性能要求极高的场景,如金融建模、物理仿真、大数据分析等。

1.1 javolution.io.Struct

此类表示 C/C++ struct;它赋予 Java 类和 C/C++ 结构之间的互操作性。

与 不同 C/C++,Java 对象的存储布局不是由编译器决定的。内存中对象的布局推迟到运行时,并由解释器(或 just-in-time 编译器)确定。此方法允许动态加载和绑定;但也使与 C/C++ 代码的接口变得困难。因此,这个类的内存布局由 的初始化顺序 Struct定义, members 并遵循与 C/C++ structs相同的 wordSize 规则。

1.2 Javolution 的核心目标

  • 低延迟:减少对象创建和垃圾回收带来的延迟。
  • 高性能:在执行数学计算、集合操作等任务时优化性能。
  • 实时支持:为需要确定性行为的应用提供稳定的响应时间。

无符号类型:Java 默认不支持无符号类型,Javolution 提供了无符号数值类型(如 Unsigned8、Unsigned16 等),在需要处理二进制数据和嵌入式开发时非常有用。

[javolution](https://javolution.org/index.html)
https://javolution.org/apidocs/javolution/io/Struct.html

2. Javolution 的使用场景

2.1 实时系统

Javolution 的设计初衷就是服务于对时延有严格要求的系统,如金融交易平台、航空航天控制系统等。通过使用 Javolution,你可以显著减少垃圾回收停顿,确保应用的响应时间。

2.2 高效数据处理

在需要处理大量数据且对内存分配敏感的场景,如数据分析、流处理,Javolution 提供了高效的集合和数学库,可以显著提高应用的运行效率。

2.3 嵌入式开发

对于内存受限、需要高效处理的嵌入式系统,Javolution 提供了轻量级的数据结构和无符号类型支持,适合嵌入式设备的开发。

3. c结构体转java

enum Gender{MALE, FEMALE};
struct Date {
    unsigned short year;
    unsigned byte month;
    unsigned byte day;
};
struct Student {
    enum Gender gender;
    char        name[64];
    struct Date birth;
    float       grades[10];
    Student*    next;
};

Java 等效类:

public enum Gender { MALE, FEMALE };
public static class Date extends Struct {
    public final Unsigned16 year = new Unsigned16();
    public final Unsigned8 month = new Unsigned8();
    public final Unsigned8 day   = new Unsigned8();
}
public static class Student extends Struct {
    public final Enum32<Gender>       gender = new Enum32<Gender>(Gender.values());
    public final UTF8String           name   = new UTF8String(64);
    public final Date                 birth  = inner(new Date());
    public final Float32[]            grades = array(new Float32[10]);
    public final Reference32<Student> next   =  new Reference32<Student>();
}

Struct 的成员可直接访问:

Student student = new Student();
student.gender.set(Gender.MALE);
student.name.set("John Doe"); // Null terminated (C compatible)
int age = 2003 - student.birth.year.get();
student.grades[2].set(12.5f);
student = student.next.get();

4. java实现结构体

依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.7.2</version>
</dependency>

<dependency>
    <groupId>javolution</groupId>
    <artifactId>javolution</artifactId>
    <version>5.5.1</version>
</dependency>

编码:

/**
 * 定义结构体
 */
public class CommonHead extends Struct {
    public Unsigned16 c0 = new Unsigned16(); //数据块长度
    public Unsigned16 c2 = new Unsigned16(); //信息类别编码
    public Unsigned8  c4  = new Unsigned8();//协议版本

    // 一定要加上这个,不然会出现对齐的问题
    @Override
    public boolean isPacked() {
        return true;
    }

    // 设置为小端数据,即最低有效字节在前 最高有效字节在后
    @Override
    public ByteOrder byteOrder() {
        return ByteOrder.LITTLE_ENDIAN;
    }
}
//在 Java 中,byte 类型的取值范围是 -128 到 127
byte[] bytes = new byte[]{0x55, (byte) 0xBB, 0x69, 0x52, 0x63};
CommonHead str = new CommonHead();
ByteBuffer b = ByteBuffer.wrap(bytes);
b.order(ByteOrder.LITTLE_ENDIAN);
str.setByteBuffer(b, 0);

System.out.println(str.c0.get());
System.out.println(str.c2.get());
System.out.println(str.c4.get());

输出内容:

47957
21097
99

在这里插入图片描述

5. 嵌套结构体

如果结构体之间有嵌套关系,我们可以在定义结构体时就以实际的嵌套关系去定义,这样就避免了多次转换

public class Eoas_V10 extends Struct {
    public CommonHead commonHead = inner(new CommonHead());
    public Unsigned8 c5 = new Unsigned8();
    public Unsigned8 c6 = new Unsigned8();
    // 一定要加上这个,不然会出现对齐的问题
    @Override
    public boolean isPacked() {
        return true;
    }

    // 设置为小端数据
    @Override
    public ByteOrder byteOrder() {
        return ByteOrder.LITTLE_ENDIAN;
    }

}
byte[] bytes = new byte[]{0x55, (byte) 0xBB, 0x69, 0x52, 0x63, 0x57, 0x08};
Eoas_V10 str = new Eoas_V10();
ByteBuffer b = ByteBuffer.wrap(bytes);
b.order(ByteOrder.LITTLE_ENDIAN);
str.setByteBuffer(b, 0);

System.out.println(str.commonHead.c0.get());
System.out.println(str.commonHead.c2.get());
System.out.println(str.commonHead.c4.get());
System.out.println(str.c5.get());
System.out.println(str.c6.get());
47957
21097
99
87
8

commonHead 占前五个字节,c5和c6占用6和7个字节,0x57, 0x08对应十进制为87和8

6. 结语

Javolution 是一个强大的 Java 库,它不仅在高性能应用中表现卓越,而且为实时系统开发提供了重要的支持。如果你正在处理复杂的数据结构、对性能有极高的要求,或者在开发嵌入式和实时系统,Javolution 无疑是一个值得探索的工具。

它通过减少垃圾回收、优化内存使用和提供高效的集合及数学库,让开发者能够编写出响应迅速、内存使用效率高的 Java 应用。在现代 Java 开发中,Javolution 是提升系统性能的强大助力。

;