在 Java 中,序列化过程通过实现 Serializable 接口自动发生,这意味着程序员无法控制幕后发生的整个过程。如果我们想序列化一个包含很多属性和属性的对象,或者使用自定义加密来操作要持久化的字节,这是不可能的。
此外,序列化一个臃肿的对象并通过网络传输它的成本很高。因此,出于许多这样的原因,我们希望对 Java 中的可序列化性进行一些控制。这就是外化发挥作用的地方。通过 Externalizable 接口的外部化机制提供了实现我们自己的序列化逻辑的机会。
因此,简而言之,如果序列化是自动将对象状态转换为字节流的机制,那么外部化也是如此,但在将对象状态转换为字节流时给予程序员控制权。
可序列化接口
在 Java 中,序列化是通过 Serializable 接口实现的。对序列化感兴趣的类在其设计期间实现此接口。因此,可以利用序列化机制的工具保存和恢复此类的实例。Serializable 接口不包含任何成员。任何实现此接口的类都表明该类的对象是可序列化的。从此类派生的任何子类也继承可序列化属性。但是,声明为瞬态或静态的成员不可序列化,因此不会持久化。
可外部化接口
Externalizable 接口提供对序列化过程的控制。与 Serializable 接口类似,实现 Externalizable 接口的类被标记为持久化,除了那些声明为瞬态或静态的成员。因为transient关键字指定了一个不被持久化的字段,所以我们可以在任何我们不想被序列化的字段上使用它。
同样,用 static 关键字标记的字段也不会仅仅因为静态字段不属于对象而是属于类而被序列化。与没有成员的 Serializable 接口相比,Externalizable 接口提供了两个方法,称为 readExternal() 和 writeExternal(),我们可以在其中编写自己的序列化规则集。
比较 Serializable 和 Externalizable 接口
一个实现 Serializable 接口的类,对象持久化会自动启动,无需程序员的任何干预。虽然是一个实现 Externalizable 接口的类,但提供序列化规范是程序员的责任。
由于在实现 Serializable 接口的情况下,序列化过程是自动的,因此该过程的性能没有改进的余地。Externalizable 接口提供对过程的完全控制,并可用于提高性能。
Serializable 和 Externalizable 接口都用于对象序列化。Serializable 接口没有成员,而 Externalizable 接口包含两个方法:readExternal() 和 writeExternal()。
结论
序列化和反序列化过程的主要用途是在没有程序员直接干预的情况下启用保存和恢复对象状态功能。这是通过 Serializable 接口自动完成的。但是,在某些情况下,我们希望控制这些过程,例如在对象序列化期间吸收压缩或加密设施。这只能通过 Enternalizable 接口实现。