开发指南141-类和字节数组转换

使用消息队列不可避免类和字节数组间转换,要使用JDK的序列化,前提条件是要实现Serializable接口。实现Serializable接口非常简单,就是定义一个常量而已。实在搞不懂这样的设计是为什么?但是既然如此,就不得不这样做。

但是很多类都没有做这个虽然简单,但是就因为简单而没有做的实现Serializable的步骤,这种情况下,如何做类和字节数组的转换?

其中之一就是使用Kryo,不废话了,直接上实现:

复制代码
<dependency>
    <groupId>com.esotericsoftware</groupId>
    <artifactId>kryo</artifactId>
    <version>5.5.0</version> 
</dependency>
复制代码
package org.qlm.util;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

public class KryoUtils {
    private static final ThreadLocal<Kryo> KRYO_THREAD_LOCAL = ThreadLocal.withInitial(() -> {
        Kryo kryo = new Kryo();
        kryo.setRegistrationRequired(false); // 不需要强制注册类
        kryo.setReferences(true); // 支持对象引用(循环引用)
        return kryo;
    });
    public static Kryo getKryo() {
        return KRYO_THREAD_LOCAL.get();
    }

    /**
     * 对象转字节数组
     * @param obj 待转换对象
     * @return 字节数组
     */
    public static byte[] serialize(Object obj) {
        if (obj == null) {
            return new byte[0];
        }
        // 从当前线程获取 Kryo 实例
        Kryo kryo = getKryo();
        // 修复:将 Output 也纳入 try-with-resources,确保资源完全释放
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
             Output output = new Output(bos)) {
            kryo.writeObject(output, obj);
            output.flush();
            return bos.toByteArray();
        } catch (Exception e) {
            throw new RuntimeException("Kryo序列化失败", e);
        }
    }

    /**
     * 字节数组转对象
     * @param bytes 字节数组
     * @param clazz 目标类类型
     * @return 还原后的对象
     */
    public static <T> T deserialize(byte[] bytes, Class<T> clazz) {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        // 从当前线程获取 Kryo 实例
        Kryo kryo = getKryo();
        // 修复:将 Input 也纳入 try-with-resources,确保资源完全释放
        try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
             Input input = new Input(bis)) {
            return kryo.readObject(input, clazz);
        } catch (Exception e) {
            throw new RuntimeException("Kryo反序列化失败", e);
        }
    }

    // 可选:手动移除当前线程的 Kryo 实例(比如线程池复用线程时,避免内存泄漏)
    public static void removeKryo() {
        KRYO_THREAD_LOCAL.remove();
    }
}
相关推荐
FreeTinker10 小时前
HTML本地存储技术解析:localStorage与sessionStorage的原理、差异与应用场景
前端·html
qq_4523962310 小时前
第十二篇:《全链路监控与可观测性:前端错误追踪与性能分析》
前端
Julien200411 小时前
控制 SELinux 文件上下文
linux·运维·服务器
EXI-小洲11 小时前
Java 操作 Word:字符串替换、图片插入、动态生成表格与API接口下载
java·开发语言·spring boot·word
wangruofeng11 小时前
Phosphor Icons 官网源码拆解:URL 即存储、水波动画与 7362 Star 图标库的架构实践
前端·架构·github
sulikey11 小时前
Linux Core Dump 完全指南:从原理到实战的崩溃调试手册。什么是core dump?程序报错core dumped怎么办?
linux·服务器·操作系统·调试·coredump
Lifangyun_WD11 小时前
第一次租 GPU 服务器怎么开始?镜像、SSH、数据存储和停机前要做什么
服务器·云计算·gpu算力·gpu算力租赁
BigTopOne11 小时前
WebRTC Native / Android 开发学习资源整理
前端
2601_9619017012 小时前
SpringBoot使用Nacos进行application.yml配置管理
java·spring boot·spring
DevLoom_12 小时前
SD卡插电脑提示:驱动器中的磁盘未被格式化?恢复数据正确处理步骤
运维·服务器·电脑