Java教程是针对JDK 8编写的。本页中描述的示例和实践不利用后续版本中引入的改进,可能使用不再可用的技术。
请参阅Java语言更改了解Java SE 9及后续版本中更新的语言特性的概述。
请参阅JDK发行说明了解有关所有JDK版本的新功能、增强功能以及已删除或已弃用选项的信息。
将对象序列化指的是将其状态转换为字节流,以便可以将字节流还原为对象的副本。如果一个Java对象的类或其任何父类实现了java.io.Serializable接口或其子接口java.io.Externalizable,那么该对象就是可序列化的。反序列化是将对象的序列化形式转换回对象副本的过程。
例如,java.awt.Button类实现了Serializable接口,因此可以对java.awt.Button对象进行序列化,并将该序列化状态存储在文件中。稍后,可以读取序列化状态并反序列化为java.awt.Button对象。
Java平台指定了序列化对象的默认方式。一个(Java)类可以覆盖此默认序列化方式,定义自己的序列化方式。详细的对象序列化说明可参考对象序列化规范。
当一个对象被序列化时,其类的标识信息会被记录在序列化流中。但是,类的定义("class file")本身不会被记录。解序列化对象的系统有责任确定如何定位和加载必要的类文件。例如,一个Java应用程序可以在其类路径中包含一个包含序列化对象的类文件的JAR文件,或者使用存储在目录中的信息来加载类定义,后面在本课程中会详细讲解。
如果底层的服务提供程序支持,您可以将可序列化对象存储在目录中,就像Oracle的LDAP服务提供程序一样。
下面的示例调用Context.bind
将一个AWT按钮绑定到名称"cn=Button"。要将属性与新绑定关联起来,可以使用DirContext.bind
。要覆盖现有的绑定,使用Context.rebind
和DirContext.rebind
。
// 创建要绑定的对象 Button b = new Button("点击我"); // 执行绑定 ctx.bind("cn=Button", b);
然后可以使用 Context.lookup
方法读取绑定的对象,如下所示。
// 检查是否已绑定 Button b2 = (Button)ctx.lookup("cn=Button"); System.out.println(b2);
运行 此示例
会产生以下输出。
# java SerObj java.awt.Button[button0,0,0,0x0,invalid,label=Push me]
注意:这里描述的过程是用于在符合RFC 2713中定义的模式的目录服务中绑定可序列化对象的过程。这些过程可能不适用于其他支持绑定带有指定代码库的可序列化对象的命名和目录服务。
当像前面的示例中所示在目录中绑定序列化对象时,从目录中读取序列化对象的应用程序必须能够访问用于反序列化对象所需的类定义。
或者,您可以在目录中与序列化对象一起记录一个代码库,无论是在绑定对象时还是随后通过使用DirContext.modifyAttributes
添加属性。您可以使用任何属性来记录此代码库,并让应用程序从目录中读取该属性并适当使用它。或者您可以使用在中指定的"javaCodebase"属性。在后一种情况下,Oracle的LDAP服务提供程序将自动使用该属性根据需要加载类定义。 "javaCodebase" 应包含代码库目录或JAR文件的URL。如果代码库包含多个URL,则每个URL之间必须用空格字符分隔。
下面的示例类似于绑定一个 java.awt.Button 的示例。不同之处在于它使用了一个用户定义的 Serializable 类 Flower
,并提供了一个包含 Flower 类定义位置的 "javaCodebase" 属性。下面是进行绑定的代码。
String codebase = ...; // 创建要绑定的对象 Flower f = new Flower("玫瑰", "粉色"); // 执行绑定并指定代码库 ctx.bind("cn=Flower", f, new BasicAttributes("javaCodebase", codebase));
当您运行此示例
时,您必须提供类文件Flower.class安装的位置的URL。例如,如果Flower.class安装在Web服务器web1的example/classes目录中,则可以按以下方式运行此示例。
# java SerObjWithCodebase http://web1/example/classes/ 粉色 玫瑰
之后,您可以从类路径中删除Flower.class,并运行任何查找或列出此对象的程序,而无需直接引用Flower类。如果您的程序直接引用Flower,则必须将其类文件提供给编译和执行。