java序列化的一些总结

少于 1 分钟阅读

  • 什么是序列化? Java序列化是指把Java对象转换为字节序列的过程,反序列化是指把字节序列恢复为Java对象的过程

  • 对象序列化的作用是什么?
    对象序列化的最主要作用就是在传递和保存对象的时候,保证对象的完整性和可传递性。序列化是把对象转换成有序字节流,以便在网络上传输或者保存在本地文件中。序列化后的字节流保存了 Java 对象的状态以及相关的描述信息。序列化的核心作用的就是对象状态的保存与重建。

  • 如何序列化?
    Java 类只需要实现 java.io.Serializable 接口,JVM 就会吧 Object 对象按照默认格式序列化。
    java.io.ObjectOutputStream 表示对象输出流,它的 writeObject(Object obj) 方法可以对参数指定的 obj 对象进行序列化,把得到的字节序列写到一个目标输出流中;
    java.io.ObjectInputStream 表示对象输入流,它的 readObject(Object obj) 方法从源输入流中读取字节序列,再把他们反序列化成一个对象,并将其返回

  • Serializable 接口的用途是什么?
    Serializable 接口中没有任何方法(标记接口),当类实现该接口,它将在 Java 中变得可序列化

  • 什么是 serialVersionUID?
    serialVersionUID 用于对象的版本控制。可以在类文件中指定 serialVersionUID。不指定 serialVersionUID 的后果是,当你添加或者修改类中的任何字段时,则已序列化类将无法恢复,因为为新类和旧序列化对象生成的 serialVersionUID 将有所不同。会引发 java.io.InvalidClassException 异常。

  • 如何实现不需要序列化某些成员?
    声明变量为静态或瞬态(transient)

  • 如果类中的一个成员未实现可序列话接口,会发生什么情况?
    NotSerializableException

  • 如果类是可序列话的,但其超类不是,则反序列化后从超类继承的示例变量的状态如何?
    Java 序列化过重仅在对象层级都是可序列化的类中继续。即反序列化一个子类时只会调用该类的反序列化过程,其中又会调用该类的构造函数,通过构造链调用父类构造函数。所以即使父类实现了序列化方法也并不会被调用。

  • 是否可以自定义序列化过程,或者说是否可以覆盖 Java 中的默认序列化过程?
    可以,重写java.io.ObjectOutputStream 表示对象输出流,它的 writeObject(Object obj) 和 java.io.ObjectInputStream 表示对象输入流,它的 readObject(Object obj)。 重写方法为私有,保证不被继承、重写或重载。但是 Java 虚拟机可以调用。

  • 假设新类的超类实现可序列化接口,如何避免新类被序列化?
    父类实现了可序列化接口,子类无法取消接口。但是可以通过重写 writeObject(Object obj) 和 readObject(Object obj) 方法,抛出异常,来避免序列化。

  • 在 Java 中的序列化和反序列化过程中使用哪些方法?
    主要 java.io.ObjectOutputStream 表示对象输出流,它的 writeObject(Object obj) 和 java.io.ObjectInputStream 表示对象输入流,它的 readObject(Object obj),这个方法返回结果需要强转

  • 假设有一个类,他序列化并存储在持久性中,然后修改了该类以添加新字段。如果对已序列化的对象进行反序列化,会发生什么情况?
    如果没有指定 serialVersionUID,可能引发 java.io.InvalidClassException 异常。

  • Java 序列化机制中的兼容更改和不兼容更改是什么?
    参考Java序列化规范

  • 在 Java 序列化期间,哪些变量未序列化?
    静态和瞬态

更新时间: