@JeromeLiee
2020-02-04T00:11:23.000000Z
字数 1249
阅读 493
序列化是将Java对象的状态按照一定规则有序地写入字节流中,反序列化就是反过来,按照一定规则从有序地从字节流读出,然后重新创建对象的过程。
因为是关于对象的状态信息保存,所以在序列化的过程,是不会对静态变量和标记了transient关键字的变量进行序列化的。
两个目的:
需要被序列化的对象实现Serializable接口,然后调用ObjectOutputStream的writeObject()方法,该方法会调用writeObject0()方法,在writeObject0()方法里,会过滤掉静态变量和标记了transient变量,接下来会检查要被序列化对象的类型,只有String、数组、枚举以及实现了Serializable接口的JavaBean才能被序列化,否则会抛出异常。检查通过后,会将对象的状态信息写入字节流中,以文件的形式存储或通过网络进行发送等。
反序列化则是将上述过程反过来,从文件中或网络中读取字节流,得到其中的对象信息,然后通过类加载器创建对象。
Serializable是个空接口,在编译后会生成一个静态long类型的serialVersionUID字段,在序列化的时候会一同写入字节流中,然后在反序列化的时候会进行该字段的校验,如果一致则创建对象,否则抛出异常。
由于编译生成的serialVersionUID会跟随类的信息变化而变化,所以我们在进行序列化操作时最好手动指定一个变量值,可以防止类信息发生变化时反序列化异常。
Android中的序列化是实现Parcelable接口,IDE会帮我们重写一系列的方法,其中序列化的过程是通过调用Parcel的一系列write方法,将JavaBean的成员变量按照顺序写入到一个Parcel对象中,这个Parcel对象可以在Binder中传输。反序列化就是将通过调用一系列的read方法,从Parcel对象中按照顺序读取字段,然后创建对象。
Serializable使用简单,但其序列化和反序列化都需要进行I/O操作,开销比较大,而Parcelable实现序列化主要用于内存中,开销小,方便跨进程Binder中传输,缺点是实现起来比较麻烦,另外想要进行持久化存储或网络传输也比较麻烦。
所以如果是想要进行持久化存储数据或用于网络传输,那么使用Serializable,如果只是想用于Binder跨进程传输,那么优先使用Parcelable。