序列化Serializable、transient和ObjectInputStream、ObjectOutputStream

前言

在IO体系中,ByteArrayInputStream可以将所有能转为byte[]的对象作为流缓存在内存里。那么如果要持久化一个对象应该怎么操作呢?
序列化与反序列化是针对java对象怎么持久化的一套操作,涉及到的知识点除了IO体系中的ObjectInputStream、ObjectOutputStream,还有序列化接口Serializable、序列化版本变量serialVersionUID、序列化禁用关键字transient、一些特有的异常等等。
所以为了形成一个整体,我在这篇文章中将它涉及到的内容都归纳到了一起。
一切源于顶层设计,首先从接口Serializable说起。

Serializable

这是一个标记对象可以被序列化的标记接口,类为Serializable。它是一个标记接口,没有定义任何行为方法。从它的JDK源码说明中,提及了其他知识点:

1. ObjectInputStream、ObjectOutputStream
2. serialVersionUID
3. transient
4. ClassNotFoundException、InvalidClassException、NotSerializableException
  1. 在Serializable接口的JDK源码说明中大概解释了下面这个意思:

Serializable是一个序列化的标记接口,只有实现了Serializable接口的类生成的对象,才能被序列化。
ObjectInputStream、ObjectOutputStream是反序列化与序列化的流化工具。ObjectInputStream、ObjectOutputStream是一个包装流,通过指定一个节点流地址,可以通过ObjectInputStream的readObject将节点流的数据反序列化成对象 或ObjectOutputStream的writeObject序列化到节点流。
在序列化与反序列化中,必须指定 serialVersionUID变量,并且是public static final 修饰,保证序列化与反序列的版本一致。否则程序将会自动随机生成serialVersionUID变量值,这可能导致序列化与反序列由于版本不一致而失败。在序列化过程中,如果不想序列化某些字段,可以通过关键字 transient修饰成员变量而阻止序列化。
如果反序列化过程中,类不存在或者serialVersionUID版本不一致或者类没有实现Serializable,都将会抛出对应的异常。

流程

为了串联本章的知识点,下面举个例子说明序列化与反序列化的流程及涉及的知识点。

  1. 序列化场景

如果想要持久化一个对象,将其保存为硬盘上的一个文件,或者想将这个对象通过网络传输到其他地方,便可以使用序列化。那么序列化是什么?和持久化有什么关系?往下看。

  1. 序列化原理

序列化是指的将一个对象(而非类)进行流化的操作。InputStream是流化的顶级父类,而对象的序列化就是指的通过ObjectInputStream将对象转为二进制序列的过程。这里指的序列化是针对对象,所以static修饰的成员变量能被序列化吗?答案显然不能。
通过序列化将对象二进制流化以后,一是可以进行读写操作,比如存为硬盘上的一个文件作为持久化,二是可以将流化后的对象通过网络传输到其他地方。

  1. 序列化条件

了解序列化的原理后,序列化需要什么条件呢?

  1. 序列化和反序列化的类必须实现Serializable接口
  2. 必须显示指定一个public static final long serialVersionUID, 序列化和反序列化的serialVersionUID值必须保持一致。
  3. 序列化必须是对象的非transient修饰的成员变量

提问

  1. 父类是可序列化类,子类是否可以实现序列化?

     由于子类继承父类,所以当父类可实现序列化时,子类也满足序列化要求。
    
  2. 子类是可序列化类,父类是否可以实现序列化?

     子类是可序列化类,父类不一定是可序列化类,所以父类可能不满足未实现Serializable接口的要求。
    
  3. 序列化对象的成员变量是否也要满足可序列化?

     序列化对象包含其成员变量的序列化,所以成员变量必须也要满足可序列化。
    
  4. 序列化的前后,成员变量不一致,是否可以反序列化?

     如果反序列化时,被序列化的成员变量仍然存在,并且满足反序列化要求时,则可以反序列化。
    

最后

序列化这一节没仔细阅读源码,感觉挺枯燥的。并且不是学习的重点,所以简笔带过。
如有不对,感谢指正!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值