这些Java教程是为JDK 8编写的。本页面中描述的示例和实践不利用后续版本中引入的改进,并且可能使用不再可用的技术。
请查看Java语言更改,了解Java SE 9及其后续版本中更新的语言特性的概要。
请查看JDK发布说明,获取有关所有JDK发布的新功能、增强功能以及已删除或已弃用选项的信息。
当一个bean的属性、字段和状态信息被保存到存储中并从存储中检索时,它具有持久性的属性。组件模型提供了一种持久性机制,可以将组件的状态存储在非易失性位置以便以后检索。
使持久性成为可能的机制称为序列化。对象序列化意味着将对象转换为数据流并将其写入存储。任何使用该bean的小程序、应用程序或工具都可以通过反序列化来"重建"它。然后,对象将恢复到其原始状态。
例如,一个Java应用程序可以在Microsoft Windows机器上序列化一个Frame窗口,然后将序列化文件通过电子邮件发送到Solaris机器,然后Java应用程序可以将Frame窗口恢复到在Microsoft Windows机器上存在的确切状态。
任何使用该bean的小程序、应用程序或工具都可以通过反序列化来"重建"它。
所有bean都必须持久化。要持久化,您的bean必须通过实现java.io.Serializable
(在API参考文档中)接口或java.io.Externalizable
(在API参考文档中)接口来支持序列化。这些接口为您提供了自动序列化和自定义序列化的选择。如果类的继承层次结构中的任何类实现了Serializable
或Externalizable
,那么该类就是可序列化的。
只要该类或父类实现了java.io.Serializable
接口,任何类都可以进行序列化。可序列化类的示例包括Component
、String
、Date
、Vector
和Hashtable
。因此,Component
类的任何子类,包括Applet
,都可以被序列化。不支持序列化的显著类包括Image
、Thread
、Socket
和InputStream
。尝试对这些类型的对象进行序列化将导致NotSerializableException
。
Java对象序列化API会自动将Serializable对象的大多数字段序列化到存储流中。这包括原始类型、数组和字符串。该API不会序列化或反序列化被标记为transient或static的字段。
您可以控制您的bean所经历的序列化级别。控制序列化的三种方式如下:
Serializable
接口实现。Java序列化软件会序列化整个对象,除了transient和static字段。transient
(或static
)修饰符标记要排除序列化的字段。Externalizable
接口及其两个方法实现。bean将以特定的文件格式编写。Serializable接口通过使用Java对象序列化工具提供自动序列化功能。Serializable接口不声明任何方法;它作为一个标记,告诉对象序列化工具你的bean类是可序列化的。将你的类标记为Serializable意味着你告诉Java虚拟机(JVM)你已经确保你的类可以与默认序列化一起工作。以下是关于使用Serializable接口的一些重要要点:
要在Serializable对象中排除字段进行序列化,可以使用transient修饰符标记这些字段。
transient int status;
默认序列化不会序列化transient和static字段。
如果你的可序列化类包含以下两个方法之一(签名必须精确),则默认序列化将不会发生。
private void writeObject(java.io.ObjectOutputStream out) throws IOException; private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;
通过编写自己的writeObject和readObject方法的实现,可以控制更复杂对象的序列化。当需要对默认序列化无法处理的对象进行序列化,或者需要向序列化流中添加非对象数据成员时,实现writeObject。通过实现readObject来重构使用writeObject编写的数据流。
当需要完全控制bean的序列化时(例如,写入和读取特定文件格式时),可以使用Externalizable接口。要使用Externalizable接口,需要实现两个方法:readExternal和writeExternal。实现Externalizable接口的类必须有一个无参数构造函数。