在学习Android的过程中,遇到了继承Serializable的类,于是乎在网上搜索了关于Serializable的作用,发现了是Java的序列化概念。
序列化简介
序列化是Java中的一个非常重要的特性,通过序列化机制,我们可以将Java的对象变成流。
例如:
永久性保存对象,保存对象数据到本地文件或者磁盘中;
对象在网络中传递,由于网络传输是以字节流的方式对数据进行传输的,因此序列化的目的是将对象数据转换成字节流的形式;
对象数据在进程间传递;
Intent之间传递复杂数据类型数据时。
注意
序列化对象的时候只是针对变量进行序列化,方法不可以。
序列化两种方式
Android中有两种序列化实现方式,分别是实现Serializable接口和Parcelable接口,其中Serializable接口是来自Java中的序列化接口,而Parcelable是Android自带的序列化接口。
1、 Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC,在性能上,Parcelable在性能方面要强于Serializable。
2、 所以在内存之间进行数据传递的时候,使用Parcelable较好,并且Parcelable是Android自带的也推荐使用Parcelable。
3、 但Parcelable有个明显的缺点,它是在内存中直接进行读写,而Serializable是通过使用IO流的形式将数据读写入在硬盘上,所以它不能在要将数据存储在磁盘上的情况(如:永久性保存对象,保存对象的字节序列到本地文件中)下使用。
4、 因为Parcel本质上为了更好的实现对象在IPC(进程间通信)间传递,并不是一个通用的序列化机制,当改变任何Parcel中数据的底层实现都可能导致之前的数据不可读取,它无法很好的将数据进行持久化,所以此时还是建议使用Serializable 。
序列化条件
Java可序列化条件这篇文章写得比较详细:
作者:Java我人生(陈磊兴) 原文出处:http://blog.csdn.net/chenleixing/article/details/43833805
1、如果子类实现Serializable接口而父类未实现时,父类不会被序列化,但此时父类必须有个无参构造方法,否则会抛InvalidClassException异常。
2、静态变量不会被序列化,那是类的“菜”,不是对象的。
3、transient关键字修饰变量可以限制序列化。
4、虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化 ID 是否一致,就是 private static final long serialVersionUID = 1L。
5、Java 序列化机制为了节省磁盘空间,具有特定的存储规则,当写入文件的为同一对象时,并不会再将对象的内容进行存储,而只是再次存储一份引用。反序列化时,恢复引用关系。
6、序列化到同一个文件时,如第二次修改了相同对象属性值再次保存时候,虚拟机根据引用关系知道已经有一个相同对象已经写入文件,因此只保存第二次写的引用,所以读取时,都是第一次保存的对象。读者在使用一个文件多次 writeObject 需要特别注意这个问题(基于第5点)。