开发指南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();
    }
}
相关推荐
漂流瓶jz13 小时前
总结CSS组件化演进之路:命名规范/CSS Modules/CSS in JS/原子化CSS
前端·javascript·css
踩着两条虫14 小时前
「AI + 低代码」的可视化设计器
开发语言·前端·低代码·设计模式·架构
Jagger_14 小时前
项目上线忙碌结束之后,为什么总想找点事做?
前端
budingxiaomoli14 小时前
Spring IoC &DI
java·spring·ioc·di
Spider Cat 蜘蛛猫14 小时前
Springboot SSO系统设计文档
java·spring boot·后端
未若君雅裁14 小时前
MySQL高可用与扩展-主从复制读写分离分库分表
java·数据库·mysql
GalenZhang88814 小时前
OpenClaw 配置多个飞书账号实战指南
前端·chrome·飞书·openclaw
学习中.........14 小时前
从扰动函数的变化,感受红黑树带来的性能提升
java
计算机安禾15 小时前
【c++面向对象编程】第24篇:类型转换运算符:自定义隐式转换与explicit
java·c++·算法
我星期八休息15 小时前
Linux系统编程—基础IO
linux·运维·服务器·c语言·c++·人工智能·算法