java实现类似C++的union

目录

1.引言

2.实际案例

3.java实现


1.引言

在C++中有一种用户自定义数据类型叫联合体union,它允许你在相同的内存位置存储不同的数据类型。与结构体(struct)不同,结构体中的所有成员都占用各自的内存空间,而 union 的所有成员共享同一块内存区域。因此,union 的大小等于其最大成员的大小。所以它的作用之一就是实现多种数据类型之间的转换

示例如下:

cpp 复制代码
#include <iostream>  
#include <cstring>  // 用于 std::memset  

union MyUnion {  
    int intValue;  
    float floatValue;  
    char charValue;  
};  

int main() {  
    MyUnion u;  

    // 设置 intValue  
    u.intValue = 42;  
    std::cout << "intValue: " << u.intValue << std::endl;  

    // 设置 floatValue(注意:这可能会覆盖 intValue 的值)  
    u.floatValue = 3.14f;  
    std::cout << "floatValue: " << u.floatValue << std::endl;  

    // 设置 charValue(再次覆盖之前的值)  
    u.charValue = 'A';  
    std::cout << "charValue: " << u.charValue << std::endl;  

    // 清空 union(使用 memset 确保内存干净,尤其是在读取之前未设置的值时)  
    std::memset(&u, 0, sizeof(u));  

    return 0;  
}

2.实际案例

在最近做的一个项目中,上位机和硬件通信,硬件会不停地把自己的一些状态参数信息上传上来,这其中包括版本号、温度、电压、解调质量等等,参数的类型大致有三种,如下图所示:

硬件为了参数上传方便,把这三种数据类型统一转换为uint64,报送给上位机,上位机根据数据类型,解析出自己的实际值,在C++语言中处理这些转换比较简单,实现如下:

uint64和char[8]转换:

定义联合体:

cpp 复制代码
union stUInt64TranString
{
	unsigned long long value;
	char    format[8];
};

比如上传的参数 "制造商" 名称为:20340163367295320

转换代码:

cpp 复制代码
stUInt64TranString y;
y.value = 20340163367295320;
cout << y.format;

uint64和double转换:

定义联合体:

cpp 复制代码
union stUInt64TranDouble
{
	unsigned long long value;
	double  value1;
};

比如上传的参数 "温度" 值为:4632233691727265792

转换代码:

cpp 复制代码
stUInt64TranDouble  x;
x.value = 4632233691727265792;
cout << x.value1;

3.java实现

uint64转char[8]:

java 复制代码
String longConvertStr(long value) {
        // 使用ByteBuffer将long值转换为字节流,并设置为小端字节序
        ByteBuffer byteBuffer = ByteBuffer.allocate(Long.BYTES).order(ByteOrder.LITTLE_ENDIAN);
        byteBuffer.putLong(value);

        // 获取字节流
        byte[] bytes = byteBuffer.array();

        // 去除字节流末尾的0
        int length = bytes.length;
        while (length > 0 && bytes[length - 1] == 0) {
            length--;
        }
        byte[] trimmedBytes = new byte[length];
        System.arraycopy(bytes, 0, trimmedBytes, 0, length);

        // 尝试将去除末尾0后的字节流转换为字符串
        return new String(trimmedBytes);
}

uint64转double:

java 复制代码
String longConvertDouble(long value) {
        ByteBuffer byteBuffer = ByteBuffer.allocate(Double.BYTES).order(ByteOrder.LITTLE_ENDIAN);
        byteBuffer.putLong(value);

        double recoveredValue = byteBuffer.getDouble(0);

        return String.valueOf(recoveredValue);
}
相关推荐
二哈赛车手1 天前
新人笔记---ApiFox的一些常见使用出错
java·笔记·spring
为何创造硅基生物1 天前
C语言 结构体内存对齐规则(通俗易懂版)
c语言·开发语言
吃好睡好便好1 天前
在Matlab中绘制横直方图
开发语言·学习·算法·matlab
栗子~~1 天前
JAVA - 二层缓存设计(本地缓冲+redis缓冲+广播所有本地缓冲失效) demo
java·redis·缓存
星寂樱易李1 天前
iperf3 + Python-- 网络带宽、网速、网络稳定性
开发语言·网络·python
YDS8291 天前
DeepSeek RAG&MCP + Agent智能体项目 —— RAG知识库的搭建和接口实现
java·ai·springboot·agent·rag·deepseek
仰泳之鹅1 天前
【C语言】自定义数据类型2——联合体与枚举
c语言·开发语言·算法
之歆1 天前
DAY_12JavaScript DOM 完全指南(二):实战与性能篇
开发语言·前端·javascript·ecmascript
未若君雅裁1 天前
MyBatis 一级缓存、二级缓存与清理机制
java·缓存·mybatis
于小猿Sup1 天前
VMware在Ubuntu22.04驱动Livox Mid360s
linux·c++·嵌入式硬件·自动驾驶