开发指南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();
    }
}
相关推荐
~央千澈~1 小时前
抖音弹幕游戏开发之第15集:添加配置文件·优雅草云桧·卓伊凡
java·前端·python
wsad05321 小时前
Shell 脚本中的多行注释和 Here Document 语法解析
前端·chrome
Trouvaille ~1 小时前
【Linux】select 多路转接深度剖析:从位图原理到字典服务器实现
linux·运维·服务器·c++·select·多路转接·io模型
mzhan0171 小时前
Linux: 重新理解调度
linux·运维·服务器
肖。35487870941 小时前
html中onclick误区,后续变量会更改怎么办?
android·java·javascript·css·html
码云数智-园园1 小时前
Java Swing 界面美化与 JPanel 优化完全指南:从复古到现代的视觉革命
java·开发语言
舟舟亢亢1 小时前
Java并发编程(下)
java·开发语言
SakitamaX1 小时前
haproxy七层代理介绍与实验
linux·运维·服务器
我是大猴子1 小时前
常见八股caffine
java·开发语言·mybatis