【Java】序列化流

Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据对象的类型对象中存储的属性等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。

反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化对象的数据对象的类型对象中存储的数据信息,都可以用来在内存中创建对象。

一、引入

首先我们来看看 序列化流 在IO流体系中的位置。序列化流是高级流,也是用来包装基本流的。

而且序列化流是属于字节流的一种,负责输出数据

与之对应的有个输入流,我们也叫做 反序列化流

它们的名字也遵守了 IO流 的命名特点

image-20240504152310552

首先我们来学习 序列化流


二、序列化流

序列化流:可以把Java中的对象写到本地文件中。

写到文件后,数据有一个特点:我们是看不懂的,但是没有关系,只要通过反序列化流将数据读取出来,读取的数据没错就行了。

但是有的同学会有疑问,如果我们想要写对象,直接将对象的属性值写到对象中不就可以了吗?而且数据还看得懂,还能修改。

你说的没错,但是坏就坏在:能看懂,能修改。在有的情况下,我是不想让别人看懂,修改的,例如游戏的存档,不想让用户自己修改。

所以这两种方式它都是有应用场景的。


三、方法

序列化流 还有一个名字:对象操作输出流,它的作用就是用来操作对象的,可以把Java中的对象写到本地文件中,是用来输出的,因此它的名字叫做 ObjectOutputStream

它本身是高级流,因此在创建对象的时候需要关联基本流。

image-20240504153306643

而且写出数据的方法也不一样了,因为现在是写出整个对象,所以方法名叫做 writeObject()

image-20240504153224458

四、代码实现

Student.java

public class Student {
    private String name;
    private int age;

    // 标准JavaBean剩下的东西,这里为了方便观看就省略了
}

测试类

//1.创建对象
Student stu = new Student("zhangsan", 23);

//2.创建序列化流的对象/对象操作输出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myio\\a.txt"));

//3.写出数据
oos.writeObject(stu);

//4.释放资源
oos.close();

运行代码,可以发现报错。

如果直接将对象写出,它会报 NotSerializableException 异常:表示这个类的对象不可被序列化。

image-20240504153838870

解决方案:需要让Javabean类实现 Serializeble接口

public class Student implements Serializable {
    private String name;
    private int age;
    // 标准JavaBean剩下的东西,这里为了方便观看就省略了
}

可以跟进看看 Serializeble接口 里面的源码,可以发现它里面没有抽象方法。

image-20240504154258269

Serializable接口 里面是没有抽象方法,像这种没有抽象方法的接口有一个专业的名字:标记型接口。

相当给 Student类 打了一个标记,一旦实现了这个接口,那么就表示当前的 Student类 可以被序列化。

简单来说 Student类的对象 可以用对象操作输出流写到本地文件。

如果没有实现 Serializeble接口 ,那就表示没有这个标记,就不能使用序列化流去序列化这个类的对象。

可以理解为:一个物品的合格证。有合格证这个物品就合格;没有合格证这个物品就不合格。

再次运行程序,可以发现没有报错,并且对象已经写入到了本地文件中了。

image-20240504155046552

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值