Java序列化——Serializable、Externalizable源码阅读与总结

本文详细介绍了Java序列化,包括什么是序列化、应用场景、Java序列化的方式(Serializable和Externalizable接口)、serialVersionUID的重要性,以及序列化与反序列化的步骤。通过示例展示了如何实现对象的序列化,并指出transient字段不会被序列化。
摘要由CSDN通过智能技术生成

一、Java序列化概述

1、什么是序列化

序列化(Serialization):是将对象的状态信息转换为可以存储或传输的形式的过程。更通俗地讲,是将该对象字段和状态信息以字节流的方式输出到目的地。

2、序列化的应用场景

  • 一是实现pojo对象的读写操作,将每个对象转换为字节流,而这些字节流可以被持久化到设备上,再次读取时会将字节流还原成对象。当我们希望某些数据能在程序停止运行后,还能继续存在。在程序再次执行时还能获取这些数据时,或者让其他的程序也能够利用这些数据资源时。这就是我理解的应用场景一。
  • 二是实现网络间的数据传输。网络间的数据传输是高频发而且数据量也是非常大的。以订单数据传输为例,当我们希望获取到订单类里的全部数据并据此生成一份订单的excel文件时,这个订单类就必须要实现序列化,这是我理解的应用场景二。

3、Java序列化的方式

Java序列化提供两种方式。

  • 一种是实现Serializable接口
    使用该方式非常简单,通过重写该接口预置的5个方法,可以达到对序列化的控制。不重写这些方法,也可以自动序列化,非常方便。
  • 另一种是实现Externalizable接口。
    不像Serializable接口只是一个标记接口,Externalizable接口强制你自己动手实现串行化和反串行化方法。它的效率比Serializable高一些,并且可以决定哪些属性需要序列化(即使是transient修饰的),但是要求必须重写两个方法。Externalizable对小数目对象有效的多。但是对大量对象,或者重复对象,则效率低。

4、Java序列化的特点

java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的”深复制”,即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。

二、Java序列化方式

Serializable接口

java.io.Serializable的源码注释大概分为以下几个点

  • java.io.Serializable是一个空接口:
public interface Serializable {
}

源码注释中说到:

* Serializability of a class is enabled by the class implementing the
 * java.io.Serializable interface. Classes that do not implement this
 * interface will not have any of their state serialized or
 * deserialized. 

大意是说,只有实现该接口的类,才能序列化和反序列化(注意,Externalizable也继承了该接口)。

  • 为了允许非序列化类的子类型进行序列化(例如,子类实现了Serializable接口,但是父类并没有实现),子类型需要承担父类的public、protected和package访问权限字段的存储和恢复任务。因此,需要父类提供一个无参的构造器,以便子类进行状态的初始化。
  • 在反序列化期间,非序列化类的字段将会被public或者protected类型的无参构造器初始化。父类的构造器必须要能够被可序列化的子类所访问。可序列化子类的字段将会被流恢复。
  • 当遍历一个图,可能会遇到一个不支持序列化接口的对象。在这种情况下,将会抛出NotSerializableException并标志该类为不可序列化。
  • 一些在序列化或者反序列化期间需要做一些特别操作的类,必须实现下面这些完整签名的方法:
private void writeObject(java.io.ObjectOutputStream out) throws IOException
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;
private void readObjectNoData() throws ObjectStreamException;
  • writeObject()方法用于将对象的当前状态写入到一个对象输出流中,并由输出流决定余下的操作(如,是输出到本地文件还是网络中)
  • readObject()负责从指定对象输入流中读出并恢复类的字段。该
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值