Serializable Objects

对对象进行“序列化”意味着将其状态转换为字节流,以便可以将字节流还原回该对象的副本。如果 Java 对象的类或其任何超类实现java\.io\.Serializableinterface或其子interfacejava\.io\.Externalizable,则该 Java 对象是“可序列化的”。 反序列化是将对象的序列化形式转换回该对象的副本的过程。

例如,java\.awt\.Button类实现Serializableinterface,因此您可以序列化java\.awt\.Button对象并将该序列化状态存储在文件中。以后,您可以读回序列化状态并将其反序列化为java\.awt\.Button对象。

Java 平台指定了序列化可序列化对象的默认方式。 (Java)类可以覆盖此默认序列化,并定义其自己的序列化该类对象的方式。 对象序列化规范详细描述了对象序列化。

序列化对象时,将标识其类的信息记录在序列化流中。但是,不记录类的定义(“类文件”)本身。对对象进行反序列化的系统负责确定如何查找和加载必要的类文件。例如,Java 应用程序可能会在其 Classpath 中包含一个 JAR 文件,该文件包含序列化对象的类文件,或者通过使用存储在目录中的信息来加载类定义,如本类后面所述。

绑定可序列化的对象

如果基础服务提供者支持该操作,则可以在目录中存储可序列化的对象,Oracle 的 LDAP 服务提供者也可以。

下面的示例调用Context.bind将 AWT 按钮绑定到名称"cn=Button"。要将属性与新绑定关联,请使用DirContext.bind。要覆盖现有绑定,请使用Context.rebindDirContext.rebind

// Create the object to be bound
Button b = new Button("Push me");

// Perform the bind
ctx.bind("cn=Button", b);

然后,您可以使用Context.lookup读回该对象,如下所示。

// Check that it is bound
Button b2 = (Button)ctx.lookup("cn=Button");
System.out.println(b2);

运行this example将产生以下输出。

# java SerObj
java.awt.Button[button0,0,0,0x0,invalid,label=Push me]

指定代码库


注意: 此处描述的过程用于在目录服务中绑定可序列化的对象,该服务遵循RFC 2713中定义的 Pattern。这些过程通常可能不适用于支持将可序列化对象与指定代码库绑定的其他命名和目录服务。


如上一示例所示,当将序列化的对象绑定到目录中时,从目录读取序列化的对象的应用程序必须有权访问反序列化该对象所必需的类定义。

或者,您可以在绑定对象时或随后通过使用DirContext.modifyAttributes添加属性来在目录中记录带有序列化对象的* codebase *。您可以使用任何属性来记录此代码库,并让您的应用程序从目录中读取该属性并适当地使用它。或者,您可以使用中指定的"javaCodebase"属性。在后一种情况下,Oracle 的 LDAP 服务提供商将根据需要自动使用该属性来加载类定义。 "javaCodebase"应该包含代码库目录或 JAR 文件的 URL。如果代码库包含多个 URL,则每个 URL 必须用空格字符分隔。

以下示例类似于用于绑定java\.awt\.Button的示例。区别在于,它使用用户定义的SerializableFlower,并提供"javaCodebase"属性,该属性包含Flower的类定义的位置。这是执行绑定的代码。

String codebase = ...;

// Create the object to be bound
Flower f = new Flower("rose", "pink");

// Perform the bind and specify the codebase
ctx.bind("cn=Flower", f, new BasicAttributes("javaCodebase", codebase));

运行this example时,必须提供安装类文件Flower\.class的位置的 URL。例如,如果将Flower\.class安装在 Web 服务器web1的目录example/classes中,则可以按以下方式运行此示例。

# java SerObjWithCodebase http://web1/example/classes/
pink rose

之后,您可以从 Classpath 中删除Flower\.class并运行任何查找或列出该对象的程序,而无需直接引用Flower类。如果您的程序直接引用Flower,则必须使其类文件可用于编译和执行。