序列化-常见面试题

2、序列化的作用

1)方便传输,速度快,还很安全,被调用方序列化,调用方反序列化即可拿到传输前最原始的java对象,常用于不同进程之间的对象传输
2)方便存储,不管是存储成文件还是数据库都可以。存储为文件,下次需要时可以直接反序列拿到对象

3、如何序列化

1)让类实现Serializable接口,该接口是一个标志性接口,标注该类对象是可被序列
2)然后使用一个输出流来构造一个对象输出流并通过writeObect(Obejct)方法就可以将实现对象写出
3)如果需要反序列化,则可以用一个输入流建立对象输入流,然后通过readObeject方法从流中读取对象

4、Serializable和Externalizable区别

  • Serializable接口基于递归算法,即在序列化过程中除字段外,还将对可通过其实例变量访问的所有对象进行序列化,即可从该对象访问的所有对象(前提是所有类都必须实现可序列化接口)。这包括直到它到达“ Object”类的对象的超类,以及直到到达那些变量的“ Object”类的实例变量的超类。基本上所有它可以读取的对象。与类相比,当我们只想保存少量变量或少量数据时,导致开销大。
  • Serializable是一个标记接口,因此不需要重写任何方法,如果实体发生更改,只需要重新编译程序即可。但是Externalizable接口必须实现writeExternal()和readExternal()包含存储和检索数据的逻辑的方法,并且可能需要对代码逻辑进行更改。
  • Serializable提供了两种选择,即可以自己处理该过程,也可以将其保留为以默认方式完成该过程,但是在Externalizable中,必须提供该过程的逻辑并完全控制序列化和反序列化处理。
  • 可序列化涉及反射机制以恢复对象。这还将在过程中添加所有可序列化类的元数据,即类描述,变量信息等,这会将大量数据和元数据添加到流中,并消耗带宽和性能问题
  • 使用Externalizable接口时需要一个公共的无参数构造函数,但是在Serializable中,它从ObjectInputStream读取所需的信息,这就是为什么使用反射机制的原因。
  • 如果需要Serializable,则需要定义serialVersionUID,如果未明确定义,它将自动生成,并且它基于类的所有字段,方法等,并且每次在类中进行更改时都会更改。如果当前ID与生成的ID不匹配,则您将无法恢复以前存储的数据。由于ID每次都会生成,因此要花费大量时间,而外部化接口却不是这种情况。
  • 与其他接口相比,Externalizable速度很快,并且占用的内存更少

5、可序列化的方法有多少?如果没有方法,那么可序列化接口的用途是什么?

可序列化 Serializalbe 接口存在于java.io包中,构成了 Java 序列化机制的核心。它没有任何方法,在 Java 中也称为标记接口。当类实现 java.io.Serializable 接口时,它将在 Java 中变得可序列化,并指示编译器使用 Java 序列化机制序列化此对象。

6、 什么是 serialVersionUID ?如果你不定义这个, 会发生什么?

它是一个 private static final long 型 ID,当它被印在对象上时, 它通常是对象的哈希码,可以使用 serialver 这个 JDK 工具来查看序列化对象的 serialVersionUID。
SerialVerionUID 用于对象的版本控制。
可以在类文件中指定 serialVersionUID。不指定 serialVersionUID的后果是,当你添加或修改类中的任何字段时, 则已序列化类将无法恢复, 因为为新类和旧序列化对象生成的 serialVersionUID 将有所不同。
Java 序列化过程依赖于正确的序列化对象恢复状态的, 并在序列化对象序列版本不匹配的情况下引发 java.io.InvalidClassException 无效类异常

7、序列化时,如何让某些成员不要序列化?

声明该成员为静态/瞬态 trasient 变量即可。

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

如果尝试序列化实现可序列化的类的对象,但该对象包含对不可序列化类的引用,则在运行时将引发不可序列化异常 NotSerializableException

9、是否可以自定义序列化过程, 或者是否可以覆盖 Java 中的默认序列化过程?

可以。对于序列化一个对象需调用 ObjectOutputStream.writeObject(saveThisObject),并用 ObjectInputStream.readObject() 读取对象。如果在类中定义这两种方法<私有>,则 JVM 将调用这两种方法,而不是应用默认序列化机制。你可以在此处通过执行任何类型的预处理或后处理任务来自定义对象序列化和反序列化的行为。

10、在 Java 中的序列化和反序列化过程中使用哪些方法?

 readObject() 、writeObject()、readExternal() 和 writeExternal()

11、可以通过网络传输一个序列化的对象吗?

可以通过网络传输序列化对象,因为 Java 序列化对象仍以字节的形式保留,字节可以通过网络发送。还可以将序列化对象存储在磁盘或数据库中作为 Blob。