Java认识序列化和反序列化(业余解析)

序列化是将对象转换为二进制字节序列,方便存储到文件或在网络上传输。反序列化则是将这些字节序列还原为对象。通过实现Serializable接口,Java类可以被序列化。文章通过示例展示了如何进行序列化和反序列化操作,并提到serialVersionUID的重要性,以及如何处理版本变化和使用transient关键字避开序列化。
摘要由CSDN通过智能技术生成

什么是序列化和反序列化,不得不说一开始看到这个略显高级的词,就被吓到了,心想这是个啥玩意呢。不过去查阅资料,一步步自习斟酌,最终也将揭开他们的面纱。

**序列化:**简单来讲就是对象转换为二进制字节序列的一个过程,而二进制字节序列就是
**反序列化:**就是将序列化反过来,将二进制字节序列转换为对象。

这样转换来转换去有啥意义呢,我们知道对象是保存到内存中的,而在对象序列化之后,我们可以将对象存储到文件当中,然后以便永久保存到磁盘上,等你需要用的时候直接反序列化出来到内存中。更重要的是,序列化之后可以用于在网络上进行传输,像什么文本,图片,视频的都是要先序列化为字节序列再进行传送的。
(打个比方:平时用微信聊天,你发送一张图片或表情包是要先转化为二进制数据,这样数据就可以存储在本地,然后通过网络协议传输到腾讯服务器,然后服务器又将该二进制数据传输到好友的微信客户端,最后客户端又将该二进制转数据换为图片,对方也就接收到了。)

序列化和反序列化的实现:
实现序列化,先要将该类实现Serializable接口,之后该类的所有方法和属性都可以进行序列化
下面将展现最常见的序列化方式:即创建字节流和对象流,并定义readObject方法和writeObject方法。

先创建一个Hero类,并将该类实现Serializable接口:

import java.io.Serializable;

public class Hero implements Serializable {
    final static long serialVersionsUID = 1L;//设置版本号
    public String name ;
    public Hero(String name){
        this.name=name;
    }
}

然后我再分别创建序列化测试类和反序列化测试类:
序列化测试类:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Test_serialize {
    public static void main(String[] args) throws IOException {
        File file = new File("D:\\桌面\\IDEA实验室\\读取.txt");
        Hero hero = new Hero("动力小子" );//创建一个Hero对象
        FileOutputStream fos = new FileOutputStream(file);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        System.out.println(hero.name);
        oos.writeObject(hero);//序列化到文件中
        oos.close();
        fos.close();
    }
}

将对象序列化到文件中,并输出了动力小子
反序列化测试类:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class Test_Deserialize {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        File file = new File("D:\\桌面\\IDEA实验室\\读取.txt");
        FileInputStream fis = new FileInputStream(file);
        ObjectInputStream ois = new ObjectInputStream(fis);
        Hero hero = new Hero("非动力小子");
        hero =(Hero)ois.readObject();//创建一个对象接收反序列化过来的对象
        System.out.println(hero.name);
        ois.close();
        fis.close();
    }
}

可以看到反序列化测试中,我创建了一个对象名为 “不是动力小子” ,如果反序列化失败了,说明没有接收到文件中返还过来的对象,输出就是 “非动力小子” ,如果反序列化成功了,输出的就是动力小子。

Hero类中的serialVersionsUID是这个序列化类的版本号,每次进行反序列化时都会对该版本号进行检查(如果没有自己手动设置,jvm会默认设置一个版本号),每次序列化后如果对Hero类中的属性和非私有方法进行增添,删除或者修改,都会改变这个类版本号,再进行反序列化就会报错,如图:
先序列化,然后添加一个属性:
在这里插入图片描述
然后反序列化,报错:
在这里插入图片描述其中第一句说:
local class incompatible: stream classdesc serialVersionUID = -7007252755224453746, local class serialVersionUID = 4876276661417299199
意思就是是本地类的UID和字节流传过来的UID不一致,为避免这种情况,一定要先更改再序列化然后反序列化。
当然如果有些属性你不想序列化,则使用 transient 关键字修饰。如图:
在这里插入图片描述
这样子这个变量就自己是一家了,别的变量跟着去序列化了他在内存里歇着,别的变量都反序列化回来了他还是歇着。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值