对象序列化与版本控制

需积分: 9 2 下载量 182 浏览量 更新于2024-08-23 收藏 86KB PPT 举报
"对象版本-对象序列化" 在Java编程中,对象序列化是一个关键的概念,它允许将对象的状态转换为字节流,以便于存储或在网络上传输。这个过程涉及到了类的版本控制,因为当类的实现发生变化时,可能会对已经序列化的对象造成影响。对象版本问题主要出现在类的序列化和反序列化之间,如果在这期间类的结构或字段发生改变,可能会导致异常。 首先,每个可序列化的类都有一个版本序列ID(serialVersionUID),这是一个长期不变的标识符,用于验证序列化过程中类的兼容性。当类的源代码发生变化,例如添加、删除或修改了字段,编译器会生成一个新的serialVersionUID。如果在反序列化时,读取的serialVersionUID与当前类的不匹配,`ObjectInputStream`会抛出`InvalidClassException`,因为找不到与序列化时相同版本的类。 在《CoreJava2, VolumnI》的"ObjectStreams"一节中提到,类的序列化方法有两种标志:SC_WRITE_METHOD 和 SC_SERIALIZABLE。SC_WRITE_METHOD 表示类重载了`writeObject()`方法,进行自定义的序列化;SC_SERIALIZABLE 表示类实现了`Serializable`接口,使用默认的序列化机制。 `Serializable`接口是Java提供的一种序列化机制,它没有包含任何方法,但实现此接口的类的对象可以被序列化。默认情况下,序列化会保存对象的类型以及对象当前状态的所有非`transient`和非`static`字段。 `DataOutputStream`类是用于将基本Java数据类型写入输出流的工具,而`ObjectOutputStream`扩展了`DataOutputStream`,进一步支持将Java对象写入输出流,包括对象的基本数据类型和图形结构。通过`ObjectOutputStream`,可以实现对象的持久存储,即保存到文件中。反之,`ObjectInputStream`可以从输入流中读取(重构)对象。 对于实现了`Serializable`接口且重写了`writeObject()`和`readObject()`方法的类,为了确保非`transient`部分能够被正确保存和恢复,必须在`writeObject()`方法中首先调用`defaultWriteObject()`,在`readObject()`方法中首先调用`defaultReadObject()`。这是因为这两个方法会处理默认的序列化和反序列化流程,如果省略,就需要手动管理对象状态的保存和恢复。 另外,如果类实现了`Externalizable`接口,那么它需要自己控制流的格式和内容,需要自定义`writeExternal()`和`readExternal()`方法来保存和恢复实例内容。这给了开发者完全的控制权,但也意味着需要额外处理与超类型的状态协调。 对象版本和序列化在Java中是复杂但重要的概念,需要谨慎处理类的变更以确保序列化和反序列化的正确性。在进行类的设计和实现时,应考虑可能的版本问题,并适当地管理序列化和反序列化的过程。