开发指南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();
    }
}
相关推荐
鹿角片ljp1 小时前
LeetCode 64:最小路径和复盘|二维 DP 与 ACM 模式完整写法
java·数据结构·算法
Madison-No71 小时前
搭建项目测试环境
linux·运维·服务器·python
+VX:Fegn08951 小时前
计算机毕业设计|基于springboot + vue蛋糕店管理系统(源码+数据库+文档)
前端·数据库·vue.js·spring boot·课程设计
泡海椒2 小时前
PDF 表格样式优化:jquick-pdf 边框、圆角、背景色
java·开发语言·pdf
悠悠121383 小时前
微服务通信别只看性能:REST 与 gRPC 的 6 个选型判断和一次 502 故障复盘
运维·服务器
Nicander3 小时前
我给 Excalidraw 做了一个本地工作区:DrawSpace
前端·开源
景熙55233 小时前
15.Java 8 Stream 流入门到实战
java·开发语言·数据结构
wno7044 小时前
Spring Security权限控制
java·python·spring
云老大-阿里云国际站代理商4 小时前
华为云国际站服务代理商:NAT网关怎么配?多台ECS共用公网IP要注意什么
服务器·华为云·云计算