安卓八股文之序列化

  • 什么是序列化

序列化是指将对象转换成可以在网络上传输或在本地保存的字节流的过程,也就是将对象的状态信息保存下来的一种机制。序列化后的字节流可以被传输到另一台机器上,并在那里进行反序列化还原成原来的对象,从而实现数据在不同系统或网络间的传输和共享。

在Java中,可以通过实现java.io.Serializable接口来实现序列化。该接口是一个标志接口,没有定义任何方法,其作用是告诉JVM该类可以被序列化。如果一个类没有实现Serializable接口,那么在序列化该对象时会抛出NotSerializableException异常。

Java序列化提供了ObjectInputStream和ObjectOutputStream两个对象来实现对象序列化和反序列化。在序列化时,将对象通过ObjectOutputStream写入字节数组或文件中;在反序列化时,将字节数组或文件通过ObjectInputStream读取并反序列化为对象。

  • 为什么需要使用序列化和反序列化

序列化和反序列化是将对象转换为字节流,以便对象在网络传输或者存储过程中能够被保存和恢复的过程。在这个过程中,对象的属性值被保存到字节流中,以便在需要的时候重新创建对象。在Java编程中,序列化和反序列化通常被用来进行分布式应用程序的开发,或者在Java对象需要被存储到磁盘或者数据库中进行持久化操作时使用。因为对象需要被以二进制格式传输,所以需要序列化和反序列化,这可以通过Java的ObjectOutputStream类和ObjectInputStream类来完成。通过序列化和反序列化,Java程序员可以实现对象的持久化和在分布式系统中进行数据传输。

  • 序列化的有哪些好处

  1. 数据持久化:通过序列化将对象保存到文件或者数据库中,数据可以长期存储,便于后续使用,同时也提高了数据的安全性。

  2. 分布式应用程序: 在分布式应用程序中,不同的进程或者机器之间需要进行对象的传递,通过序列化对象可以以二进制格式传递对象,并且可以保持对象的状态。

  3. 网络编程:通过序列化和反序列化,Java程序员可以实现对象在网络中的传输,这样可以大大减少网络传输量、提高网络传输效率以及降低网络延迟。

  4. 缓存: 序列化可以帮助持久化缓存对象,缓存对象可以更稳定,不易异常。

  • Serializable 和 Parcelable 的区别

Serializable 和 Parcelable 都可以实现Java对象的序列化,但是两者是不同的机制,具有一些区别。

  1. 粒度不同。Serializable是以对象为粒度进行序列化,而 Parcelable 是以Parcelable对象为粒度进行序列化,因此 Parcelable 比 Serializable 快一些。

  2. 效率不同。由于 Serializable 是利用反射实现的,它的序列化和反序列化处理相对较慢,而 Parcelable 利用直接内存存取,速度相对更快。

  3. 接口不同。Serializable 接口位于java.io包中,而 Parcelable 接口位于android.os包中,因此在 Android 开发中,Parcelable 接口更加常用。

  4. 支持数据类型不同。Serializable 接口默认支持Java的所有原始数据类型和对象类型,而 Parcelable 接口则需要手动实现支持的数据类型。

  • 什么是serialVersionUID

serialVersionUID是一个Java类的静态变量,用于确定该类的序列化版本。它用来控制反序列化过程中对象版本的兼容性。当Java对象被序列化后,它会成为一个字节序列,该字节序列包含类的名称、序列化版本号和所有成员变量的值。在反序列化的过程中,JVM会读取序列化版本号,并检查与当前类定义的版本号是否匹配,如果序列化版本号与当前类定义的版本号不同,则会抛出InvalidClassException异常。

如果一个类的 serialVersionUID 没有被定义,JVM会根据该类的各个组成部分自动生成一个 serialVersionUID,因此在反序列化时可能会出现版本不匹配的情况导致错误。因此,建议在每个可序列化的类中都定义 serialVersionUID。

  • 为什么还要显示指定serialVersionUID的值?

虽然 JVM 在运行时会根据类的各个方面自动生成 serialVersionUID 值,但是生成规则比较复杂,很难手动控制。因此,在一些特殊情况下,如果不显示指定serialVersionUID,可能会出现以下问题:

  1. 修改类的成员变量,会导致 serialVersionUID 的值发生改变,从而可能导致反序列化失败;
  2. 不同的 JVM 实现方式可能会导致自动生成的 serialVersionUID 不同,因此在不同的JVM平台之间传递序列化对象时,可能会出现问题;
  3. 如果序列化的类只是用于内部通信,而不会在不同的系统之间传递,显示指定 serialVersionUID 可以避免随着时间的推移,JVM 自动生成的serialVersionUID 发生改变,导致反序列化失败。

在上述情况下,显示指定 serialVersionUID 的值,可以保证反序列化的稳定性和可靠性。为了安全起见,在声明的类中声明一个private static final long serialVersionUID属性。

猜你喜欢

转载自blog.csdn.net/slave_of_life/article/details/130772635