"Externalizable接口是Java中用于对象序列化的一个重要接口,它扩展了Serializable接口,给予类完全控制其序列化状态的权利。对象序列化是将对象的状态转换为字节流,以便于存储或在网络中传输。当一个类实现Externalizable接口时,意味着该类负责其实例内容的保存和恢复,而不是依赖于Java默认的序列化机制。
在实现Externalizable接口的类中,开发者必须提供两个关键方法:`readExternal(ObjectInputStream in)`和`writeExternal(ObjectOutputStream out)`。这两个方法分别用于从输入流中读取对象状态并恢复,以及将对象状态写入输出流进行保存。由于Externalizable对象的序列化和反序列化过程完全由程序员控制,因此可以更精细地处理哪些字段需要序列化,哪些不需要,甚至可以处理子对象的重建。
与实现Serializable接口不同,后者默认会保存对象的类型和当前状态,而Externalizable接口允许开发者完全自定义序列化和反序列化的过程。在反序列化时,对于一个Externalizable对象,系统首先会调用无参构造函数创建一个新的对象实例,然后调用`readExternal()`方法来填充对象状态。而对于实现了Serializable接口但未实现Externalizable的类,Java会调用默认的序列化机制,这通常包括保存对象的类型信息,创建新的对象实例,并用输入流中的数据填充。
如果一个类实现了Serializable接口并且重写了`writeObject()`和`readObject()`方法,那么为了保存非transient字段,需要在`writeObject()`中首先调用`defaultWriteObject()`,并在`readObject()`中首先调用`defaultReadObject()`。这样做可以确保默认的序列化行为和自定义行为结合。如果不这样做,那么必须手动处理每个字段的保存和恢复。
在实际应用中,选择实现Serializable还是Externalizable取决于具体需求。Externalizable提供了更大的灵活性,但也需要编写更多的代码,特别是在处理复杂对象结构时。而Serializable则相对简单,适合大多数不需要特殊序列化逻辑的情况。
在《CoreJava2, VolumnI》的"ObjectStreams"章节中,详细讨论了如何使用ObjectOutputStream和ObjectInputStream进行对象的序列化和反序列化,同时也提到了关于类序列化方法的标志,如SC_WRITE_METHOD和SC_SERIALIZABLE,这些都是用来标记类是否具有自定义序列化方法的标志。
Externalizable接口是Java对象序列化的一种高级形式,允许开发者自定义序列化流程,适用于需要精细控制序列化行为的场景。同时,理解并正确使用Serializable和Externalizable接口,对于优化对象持久化和网络传输的效率至关重要。"