JDK自带的序列化框架使用

本文详细介绍了Java中对象序列化的过程,从基本的String对象到复杂User类的序列化,包括使用JDK Serializable接口、serialVersionUID的作用,以及JDK自带序列化的优缺点。讨论了跨语言调用和性能问题,并列举了JDK支持的数据类型。
摘要由CSDN通过智能技术生成

目录

序列化的定义

在Java中如何将一个对象序列化呢?

一个复杂对象如何进行序列化呢?

缺点:

JDK自带的序列化支持的数据类型


序列化的定义

序列化:把对象转化为可传输的字节序列过程称为序列化。

反序列化:把字节序列还原为对象的过程称为反序列化。

序列化最终的目的是为了对象可以跨平台存储,和进行网络传输。而我们进行跨平台存储和网络传输的方式就是IO,而我们的IO支持的数据格式就是字节数组。

在Java中如何将一个对象序列化呢?

最简单的把一个 String对象转化为字节流,再把字节流转化为一个String对象。

 // string 转成 byte[]
    public static byte[] stringToBytes(String str) {
        //  只支持英文字符
        if (str == null || str.length() == 0) {
            // 如果字符串为 null 或者为空 都是空的byte数组
            return new byte[0];
        }
        byte[] bytes = new byte[str.length()];
        char[] chars = str.toCharArray();
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) chars[i];
        }
        return bytes;
    }
 
    public static String byteToString(byte[] bytes) {
        if (bytes.length == 0) {
            return null;
        }
        int len = bytes.length;
        char[] charArray = new char[len];
        for (int i = 0; i < bytes.length; i++) {
            charArray[i] = (char) bytes[i];
        }
        return String.valueOf(charArray);
    }

Java实现简单类的序列化(int 和 string字段的序列化)_trigger333的博客-CSDN博客

一个复杂对象如何进行序列化呢?

比如一个User对象,

public class User{

    private Integer id;

    private String username;
}

 这时可以使用jdk自带的序列化框架 JDK Serializable,只需要实现Serializable接口,就可以进行序列化。

public class User implements Serializable {

    private static final long serialVersionUID = 5342726393385586669L;

    private Integer id;

    private String username;
}

JDK Serializable中通过serialVersionUID控制序列化类的版本,如果序列化与反序列化版本不一致,则会抛出java.io.InvalidClassException异常信息,提示序列化与反序列化SUID不一致。一般会手动指定SUID。

Java 序列化详解_Gerald Newton的博客-CSDN博客_java序列化详解

public class JdkSerializeFactory implements SerializeFactory {


    @Override
    public <T> byte[] serialize(T t) {
        byte[] data = null;
        try {
//            字节数组输出流在内存中创建一个字节数组缓冲区,所有发送
//            到输出流的数据保存在该字节数组缓冲区中。
//            创建字节数组输出流对象有以下几种方式。
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ObjectOutputStream output = new ObjectOutputStream(os);
            output.writeObject(t);
            //bugfix 解决readObject时候出现的eof异常
            output.writeObject(null);
            output.flush();
            data = os.toByteArray();
            // 关闭
            output.close();
            os.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return data;
    }

    @Override
    public <T> T deserialize(byte[] data, Class<T> clazz) {
        ByteArrayInputStream is = new ByteArrayInputStream(data);
        try {
            ObjectInputStream input = new ObjectInputStream(is);
            Object result = input.readObject();
            return ((T) result);
        } catch (IOException | ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

}

缺点:

  1. 不支持跨语言调用 : 如果调用的是其他语言开发的服务的时候就不支持了。
  2. 性能差 :相比于其他序列化框架性能更低,主要原因是序列化之后的字节数组体积较大,导致传输成本加大,同时在序列化反序列化的时候耗时比较长。

JDK自带的序列化支持的数据类型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

trigger333

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值