开发指南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();
    }
}
相关推荐
mCell12 小时前
【锐评】桌面端技术营销:别拿跑分当工程判断
前端·rust·electron
柒和远方13 小时前
从一次工程审查看 AI 学习产品的边界兜底:RAG 资料链路一致性实战
前端·后端·架构
疯狂的魔鬼13 小时前
一个"懂分寸"的文本省略组件是怎样炼成的
前端·vue.js·设计
angerdream13 小时前
手把手编写儿童手机远程监控App之vue3 AI Gent
前端
亦暖筑序13 小时前
Java 8老系统Browser Agent实战:三层拦截把AI操作后台变成可审计流程
java·后端·设计模式
李明卫杭州13 小时前
CSS BFC 完全指南:从原理到实战,彻底搞懂这个"结界"
前端
Momo__13 小时前
MDN MCP Server——Mozilla 把 Web 文档接进 AI Agent,从此 LLM 不再瞎编 API
前端·ai编程·mcp
妙码生花13 小时前
现代前端的极致性能 icon 加载方案(死磕成功版)
前端·vue.js·typescript
掘金者阿豪14 小时前
把业务数据变成共享仪表盘:Metabase可视化与远程访问实践
前端·后端
kyriewen14 小时前
折腾了半年 AI 编程工作流,最后发现效率瓶颈是桌上那块屏幕
前端·javascript·ai编程