Android面试专题(十):序列化原理 深入再理解

2,744 阅读5分钟

不诗意的女程序媛不是好厨师~ 转载请注明出处,From李诗雨—blog.csdn.net/cjm24848365…

(PS:感觉面试的时候如果真的可以把这些点说出来,会显得比较高级,而且还可以使我们的面试时间显得很长,哈哈哈哈哈~)

在这里插入图片描述

面试官:“你能说一下Java 与 Android 的序列化原理吗?”

是的,我们之前复习了一遍《Serializable 和 Parcelable 的区别》,但是 Serializable接口 和 Parcelable接口并不等于序列化,如果要再让我们讲一下序列化的原理,我们就要再多知道一点。

首先我们要明白一个概念:什么是序列化?

  • 序列化与反序列化都是一个过程,它并不是一个接口!

    序列化就是说当我需要保存信息到内存中或者文件里的时候,我要对这些信息做一些标记和标准规范。

    反序列化就是 将来要用到这些信息的时候 可以按照你保存时的逻辑 恢复成你保存之前的样子。

再拿个现实生活中例子,来形象的类比一下。

大家都有搬家的经历,在搬家的时候,比如你有一个很大的可拆卸的柜子,这个时候为了方便,我们会把柜子拆卸之后装箱,在拆卸装箱的时候我会做一些标记,或者制定一些标准,因为我要保证我拆过之后,还能把它拼回原样。---那这种做标记或者按照标准装箱的过程,我们就可以把它理解为序列化。

到了新家之后,我们拆开箱子,按照之前做的标记(或者定下的标准)我们能够很容易的把柜子恢复成原来的样子。---那这种遵循一定的规则能够恢复原样的过程,我们就可以把它理解为反序列化。

所以,这个时候我们明白了 Serializable 和 Parcelable 只是实现序列化的手段之一二而已。

下面,我再来深入的看看它们到底是怎么实现序列化的,原理又是什么?

先说Serializable吧,下面是它的源代码:

在这里插入图片描述
恩,你可以看到Serializable接口是空的!

  • 既然是空的,它是怎么做到序列化的呢?

    其实啊,这个接口本身并没有做什么,它在这里只是充当了标记的作用。

    有没有发现,在源码的注释里有ObjectOutputStream、ObjectIntputStream、ObjectOutput、ObjectInput。

    这就是说,只要你的类打上了“Serializable”这个标记,就可以使用outputStream这个流把它写出去,如果没有打上这个标记你就去用流写的话,它就会抛出一个异常。

  • 那打上这个标记之后,它是如何做到序列化与反序列化的呢?

    这后续的操作就是由JDK自己完成的了。

    比如说我现在有一个Student类 要通过io流把它写到文件中去,这个时候我就必须让它实现Serializable接口。

    使用之后,当你用流去写的时候,jdk自己就会把这个类中的所有属性(类型/值/名字等所有信息)打包写到一个文件中去。

    这样在以后别人要用它的时候,就能根据标记来恢复,这是一个逆向的过程,所以叫做反序列化。

    当然,它底层其实是用的反射,用反射去获取类的属性、名字等等信息。

由于Parcelable是android提供的一个接口。所以它就不再是空的实现了。

还是让我们来看一看源码吧:

在这里插入图片描述

因为Parcelable要自己去实现序列化与反序列化,所以它的使用就复杂了很多,在它的注释中也告诉了我们如何去实现Parcelable.

当我们序列化的时候就会去调用writeToParcel()方法,把数据记录到Parcel里去。

它序列化和反序列化的顺序必须相同,不需要借助io。

通看下来,我们可以知道:

  • Serializable是JDK的规则,具体的序列化 反序列化操作都是有jdk完成的。

  • Parcelable需要程序员来自己实现序列化与反序列化过程,所以Parcelable使用的时候效率要比Serializable高,但是使用的时候要比Serializable复杂(自己写代码)。

  • 但是我们也发现:他们二者的共同目的是相同的---即把我们的数据按照一定的规则记录下来,如果你需要反序列化的时候 就把数据按照规则给解析恢复出来。

到此我们深深的体会到了 序列化与反序列化都是一个过程,并不是一个接口这句话了。

并且我们也体会并理解了Serializable、Parcelable都只是实现序列化与反序列的一种方式、一种规则而已。

那我们不经又想到,我们会经常向网络传输数据,也会从网络上获取数据。而它们并没有实现Serializable/Parcelable,那它们又是怎么做的序列化与反序列化的呢?

这个问题其实也不难,大家想想我们在进行网络数据传输的时候都是用的什么呀?

是不是Gson啊、FastJson啊之类的,那我们不难猜测,它们肯定也去实现了序列化与反序列化,只是它们用的是自己的规则而已,比如json。

json这种序列化的方案,它的有点还是很突出的,那就是方便我们进行网络调试,哪里有问题,数据一看就知道了,可读性杠杠滴。

积累点滴,做好自己~