public class ObjectOutputStream
extends OutputStream
implements ObjectOutput, ObjectStreamConstants
java.lang.Object | ||
↳ | java.io.OutputStream | |
↳ | java.io.ObjectOutputStream |
ObjectOutputStream将Java对象的基本数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重建)对象。 对象的持久存储可以通过使用流的文件来完成。 如果流是网络套接字流,则可以在另一个主机或另一个进程中重新构建对象。
只有支持java.io.Serializable接口的对象才能写入流。 每个可序列化对象的类都被编码,包括类的类名和签名,对象的字段和数组的值以及从初始对象引用的任何其他对象的关闭。
writeObject方法用于将对象写入流中。 任何对象,包括字符串和数组,都是用writeObject写的。 可以将多个对象或基元写入流中。 这些对象必须从相应的ObjectInputstream中以相同的类型和顺序读回。
原始数据类型也可以使用DataOutput中的适当方法写入流。 字符串也可以使用writeUTF方法写入。
对象的默认序列化机制将写入对象的类,类签名以及所有非瞬态和非静态字段的值。 对其他对象(除了在瞬态或静态字段中)的引用也会导致写入这些对象。 对单个对象的多个引用使用引用共享机制进行编码,以便可以将对象的图形恢复为与原始写入时相同的形状。
例如,编写ObjectInputStream中的示例可以读取的对象:
FileOutputStream fos = new FileOutputStream("t.tmp"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeInt(12345); oos.writeObject("Today"); oos.writeObject(new Date()); oos.close();
在序列化和反序列化过程中需要特殊处理的类必须实现具有以下精确特征的特殊方法:
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException; private void writeObject(java.io.ObjectOutputStream stream) throws IOException private void readObjectNoData() throws ObjectStreamException;
writeObject方法负责为其特定类编写对象的状态,以便相应的readObject方法可以恢复它。 该方法不需要关注属于该对象的超类或子类的状态。 状态通过使用writeObject方法将单个字段写入ObjectOutputStream或使用DataOutput支持的基本数据类型的方法来保存。
序列化不会写出没有实现java.io.Serializable接口的任何对象的字段。 不可序列化的对象的子类可以是可序列化的。 在这种情况下,不可序列化的类必须有一个无参数构造函数来允许其字段被初始化。 在这种情况下,保存和恢复不可序列化类的状态是子类的责任。 通常情况下,该类的字段是可访问的(public,package或protected),或者有可用于恢复状态的get和set方法。
通过实现抛出NotSerializableException的writeObject和readObject方法可以防止对象的序列化。 该异常将被ObjectOutputStream捕获并中止序列化过程。
实现Externalizable接口允许对象完全控制对象序列化表单的内容和格式。 调用Externalizable接口的方法writeExternal和readExternal来保存和恢复对象状态。 当由类实现时,他们可以使用ObjectOutput和ObjectInput的所有方法编写和读取自己的状态。 对象负责处理发生的任何版本控制。
序列化常量与普通的可序列化或可外部化的对象不同。 枚举常量的序列化形式仅由其名称组成; 不传送常量的字段值。 要序列化一个枚举常量,ObjectOutputStream会写入常量名称方法返回的字符串。 像其他可序列化或可外部化的对象一样,枚举常量可以用作后续出现在序列化流中的后向引用的目标。 枚举常量序列化的过程不能自定义; 序列化过程中会忽略由枚举类型定义的任何特定于类的writeObject和writeReplace方法。 同样,也会忽略任何serialPersistentFields或serialVersionUID字段声明 - 所有枚举类型都有一个固定的serialVersionUID 0L。
原始数据(不包括可序列化字段和可外部化数据)被写入块数据记录中的ObjectOutputStream。 块数据记录由头和数据组成。 块数据头由一个标记和头后的字节数组成。 连续的原始数据写入被合并到一个块数据记录中。 用于块数据记录的阻塞因子将是1024个字节。 每个块数据记录最多可以填充1024个字节,或者在块数据模式终止时写入。 调用ObjectOutputStream方法writeObject,defaultWriteObject和writeFields最初会终止任何现有的块数据记录。
也可以看看:
Nested classes |
|
---|---|
class |
ObjectOutputStream.PutField 提供对写入ObjectOutput的持久字段的编程访问。 |
Inherited constants |
---|
From interface java.io.ObjectStreamConstants
|
Inherited fields |
---|
From interface java.io.ObjectStreamConstants
|
Public constructors |
|
---|---|
ObjectOutputStream(OutputStream out) 创建写入指定OutputStream的ObjectOutputStream。 |
Protected constructors |
|
---|---|
ObjectOutputStream() 为完全重新实现ObjectOutputStream的子类提供一种方法,使其不必分配此ObjectOutputStream实现所使用的私有数据。 |
Public methods |
|
---|---|
void |
close() 关闭流。 |
void |
defaultWriteObject() 将当前类的非静态和非瞬态字段写入此流。 |
void |
flush() 刷新流。 |
ObjectOutputStream.PutField |
putFields() 检索用于缓冲要写入流的持久字段的对象。 |
void |
reset() 重置将忽略已写入流的任何对象的状态。 |
void |
useProtocolVersion(int version) 指定流编写时使用的流协议版本。 |
void |
write(byte[] buf) 写入一个字节数组。 |
void |
write(byte[] buf, int off, int len) 写入一个字节的子数组。 |
void |
write(int val) 写一个字节。 |
void |
writeBoolean(boolean val) 写入一个布尔值。 |
void |
writeByte(int val) 写入一个8位字节。 |
void |
writeBytes(String str) 以字节序列写入一个字符串。 |
void |
writeChar(int val) 写入一个16位字符。 |
void |
writeChars(String str) 将字符串作为字符序列写入。 |
void |
writeDouble(double val) 写入一个64位双。 |
void |
writeFields() 将缓冲区域写入流中。 |
void |
writeFloat(float val) 写入一个32位浮点数。 |
void |
writeInt(int val) 写入32位int。 |
void |
writeLong(long val) 写入64位长。 |
final void |
writeObject(Object obj) 将指定的对象写入ObjectOutputStream。 |
void |
writeShort(int val) 写一个16位短。 |
void |
writeUTF(String str) 以 modified UTF-8格式写入此字符串的原始数据。 |
void |
writeUnshared(Object obj) 将一个“非共享”对象写入ObjectOutputStream。 |
Protected methods |
|
---|---|
void |
annotateClass(Class<?> cl) 子类可以实现此方法以允许类数据存储在流中。 |
void |
annotateProxyClass(Class<?> cl) 子类可以实现此方法以将自定义数据与动态代理类的描述符一起存储在流中。 |
void |
drain() 排除ObjectOutputStream中的任何缓冲数据。 |
boolean |
enableReplaceObject(boolean enable) 启用流来替换流中的对象。 |
Object |
replaceObject(Object obj) 此方法将允许ObjectOutputStream的可信子类在序列化期间将一个对象替换为另一个对象。 |
void |
writeClassDescriptor(ObjectStreamClass desc) 将指定的类描述符写入ObjectOutputStream。 |
void |
writeObjectOverride(Object obj) 子类用于覆盖默认的writeObject方法的方法。 |
void |
writeStreamHeader() 提供了writeStreamHeader方法,以便子类可以将它们自己的头添加或添加到流中。 |
Inherited methods |
|
---|---|
From class java.io.OutputStream
|
|
From class java.lang.Object
|
|
From interface java.io.Closeable
|
|
From interface java.io.Flushable
|
|
From interface java.io.ObjectOutput
|
|
From interface java.lang.AutoCloseable
|
|
From interface java.io.DataOutput
|
ObjectOutputStream (OutputStream out)
创建写入指定OutputStream的ObjectOutputStream。 这个构造函数将序列化流头写入基础流; 调用者可能希望立即刷新流,以确保接收ObjectInputStreams的构造函数在读取头时不会阻塞。
如果安装了安全管理器,则此构造函数将直接或间接地由覆盖ObjectOutputStream.putFields或ObjectOutputStream.writeUnshared方法的子类的构造函数调用时检查“enableSubclassImplementation”SerializablePermission。
Parameters | |
---|---|
out |
OutputStream : output stream to write to |
Throws | |
---|---|
IOException |
if an I/O error occurs while writing stream header |
SecurityException |
if untrusted subclass illegally overrides security-sensitive methods |
NullPointerException |
if out is null |
ObjectOutputStream ()
为完全重新实现ObjectOutputStream的子类提供一种方法,使其不必分配此ObjectOutputStream实现所使用的私有数据。
如果安装了安全管理器,则此方法首先使用 SerializablePermission("enableSubclassImplementation")
权限调用安全管理器的 checkPermission
方法,以确保可以启用子类化。
Throws | |
---|---|
SecurityException |
if a security manager exists and its checkPermission method denies enabling subclassing. |
IOException |
void close ()
关闭流。 必须调用此方法才能释放与流关联的所有资源。
Throws | |
---|---|
IOException |
If an I/O error has occurred. |
void defaultWriteObject ()
将当前类的非静态和非瞬态字段写入此流。 这只能从被序列化的类的writeObject方法中调用。 如果它被调用,它会抛出NotActiveException。
Throws | |
---|---|
IOException |
if I/O errors occur while writing to the underlying OutputStream |
void flush ()
刷新流。 这将写入任何缓冲的输出字节并刷新到基础流。
Throws | |
---|---|
IOException |
If an I/O error has occurred. |
ObjectOutputStream.PutField putFields ()
检索用于缓冲要写入流的持久字段的对象。 调用writeFields方法时,这些字段将写入流中。
Returns | |
---|---|
ObjectOutputStream.PutField |
an instance of the class Putfield that holds the serializable fields |
Throws | |
---|---|
IOException |
if I/O errors occur |
void reset ()
重置将忽略已写入流的任何对象的状态。 状态被重置为与新的ObjectOutputStream相同。 流中的当前点标记为重置,因此相应的ObjectInputStream将在同一点重置。 以前写入流的对象不会被认为已经在流中。 他们会再次被写入流中。
Throws | |
---|---|
IOException |
if reset() is invoked while serializing an object. |
void useProtocolVersion (int version)
指定流编写时使用的流协议版本。
此例程提供了一个挂钩,以使当前版本的Serialization能够以与以前版本的流格式向后兼容的格式进行写入。
将尽一切努力避免引入额外的逆向不兼容性; 但是,有时候没有其他选择。
Parameters | |
---|---|
version |
int : use ProtocolVersion from java.io.ObjectStreamConstants. |
Throws | |
---|---|
IllegalStateException |
if called after any objects have been serialized. |
IllegalArgumentException |
if invalid version is passed in. |
IOException |
if I/O errors occur |
void write (byte[] buf)
写入一个字节数组。 该方法将阻塞,直到字节被实际写入。
Parameters | |
---|---|
buf |
byte : the data to be written |
Throws | |
---|---|
IOException |
If an I/O error has occurred. |
void write (byte[] buf, int off, int len)
写入一个字节的子数组。
Parameters | |
---|---|
buf |
byte : the data to be written |
off |
int : the start offset in the data |
len |
int : the number of bytes that are written |
Throws | |
---|---|
IOException |
If an I/O error has occurred. |
void write (int val)
写一个字节。 该方法将阻塞,直到字节被实际写入。
Parameters | |
---|---|
val |
int : the byte to be written to the stream |
Throws | |
---|---|
IOException |
If an I/O error has occurred. |
void writeBoolean (boolean val)
写入一个布尔值。
Parameters | |
---|---|
val |
boolean : the boolean to be written |
Throws | |
---|---|
IOException |
if I/O errors occur while writing to the underlying stream |
void writeByte (int val)
写入一个8位字节。
Parameters | |
---|---|
val |
int : the byte value to be written |
Throws | |
---|---|
IOException |
if I/O errors occur while writing to the underlying stream |
void writeBytes (String str)
以字节序列写入一个字符串。
Parameters | |
---|---|
str |
String : the String of bytes to be written |
Throws | |
---|---|
IOException |
if I/O errors occur while writing to the underlying stream |
void writeChar (int val)
写入一个16位字符。
Parameters | |
---|---|
val |
int : the char value to be written |
Throws | |
---|---|
IOException |
if I/O errors occur while writing to the underlying stream |
void writeChars (String str)
将字符串作为字符序列写入。
Parameters | |
---|---|
str |
String : the String of chars to be written |
Throws | |
---|---|
IOException |
if I/O errors occur while writing to the underlying stream |
void writeDouble (double val)
写入一个64位双。
Parameters | |
---|---|
val |
double : the double value to be written |
Throws | |
---|---|
IOException |
if I/O errors occur while writing to the underlying stream |
void writeFields ()
将缓冲区域写入流中。
Throws | |
---|---|
IOException |
if I/O errors occur while writing to the underlying stream |
NotActiveException |
Called when a classes writeObject method was not called to write the state of the object. |
void writeFloat (float val)
写入一个32位浮点数。
Parameters | |
---|---|
val |
float : the float value to be written |
Throws | |
---|---|
IOException |
if I/O errors occur while writing to the underlying stream |
void writeInt (int val)
写入32位int。
Parameters | |
---|---|
val |
int : the integer value to be written |
Throws | |
---|---|
IOException |
if I/O errors occur while writing to the underlying stream |
void writeLong (long val)
写入64位长。
Parameters | |
---|---|
val |
long : the long value to be written |
Throws | |
---|---|
IOException |
if I/O errors occur while writing to the underlying stream |
void writeObject (Object obj)
将指定的对象写入ObjectOutputStream。 对象的类,类的签名以及类和它的所有超类型的非瞬态和非静态字段的值被写入。 使用writeObject和readObject方法可以覆盖类的默认序列化。 这个对象引用的对象是可传递的,因此一个完整的等价对象图可以通过ObjectInputStream重构。
引发OutputStream问题和不应序列化的类的异常。 所有异常对于处于不确定状态的OutputStream都是致命的,取决于调用者忽略或恢复流状态。
Parameters | |
---|---|
obj |
Object : the object to be written |
Throws | |
---|---|
InvalidClassException |
Something is wrong with a class used by serialization. |
NotSerializableException |
Some object to be serialized does not implement the java.io.Serializable interface. |
IOException |
Any exception thrown by the underlying OutputStream. |
void writeShort (int val)
写一个16位短。
Parameters | |
---|---|
val |
int : the short value to be written |
Throws | |
---|---|
IOException |
if I/O errors occur while writing to the underlying stream |
void writeUTF (String str)
以modified UTF-8格式写入此字符串的原始数据。 请注意,将字符串作为原始数据或作为对象写入流之间存在显着差异。 由writeObject写入的String实例最初作为String写入流中。 未来的writeObject()调用将对字符串的引用写入流中。
Parameters | |
---|---|
str |
String : the String to be written |
Throws | |
---|---|
IOException |
if I/O errors occur while writing to the underlying stream |
void writeUnshared (Object obj)
将一个“非共享”对象写入ObjectOutputStream。 此方法与writeObject相同,不同之处在于它始终将给定对象作为新的唯一对象写入流中(而不是指向先前序列化的实例的后向引用)。 特别:
重写此方法的ObjectOutputStream子类只能在拥有“enableSubclassImplementation”SerializablePermission; 任何尝试实例化没有此权限的子类都将导致抛出SecurityException。
Parameters | |
---|---|
obj |
Object : object to write to stream |
Throws | |
---|---|
NotSerializableException |
if an object in the graph to be serialized does not implement the Serializable interface |
InvalidClassException |
if a problem exists with the class of an object to be serialized |
IOException |
if an I/O error occurs during serialization |
void annotateClass (Class<?> cl)
子类可以实现此方法以允许类数据存储在流中。 默认情况下这个方法什么都不做 ObjectInputStream中的相应方法是resolveClass。 对于流中的每个唯一类,此方法只会被调用一次。 类名和签名将已经写入流中。 该方法可以免费使用ObjectOutputStream来保存它认为合适的类的任何表示(例如,类文件的字节)。 ObjectInputStream相应子类中的resolveClass方法必须读取并使用由annotateClass编写的任何数据或对象。
Parameters | |
---|---|
cl |
Class : the class to annotate custom data for |
Throws | |
---|---|
IOException |
Any exception thrown by the underlying OutputStream. |
void annotateProxyClass (Class<?> cl)
子类可以实现此方法以将自定义数据与动态代理类的描述符一起存储在流中。
对于流中的每个唯一代理类描述符,该方法只会被调用一次。 此方法在ObjectOutputStream
中的默认实现不做任何事情。
ObjectInputStream
的相应方法是resolveProxyClass
。 对于给定的子类ObjectOutputStream
重写该方法中, resolveProxyClass
中的相应子类方法ObjectInputStream
必须读取由写任何数据或对象annotateProxyClass
。
Parameters | |
---|---|
cl |
Class : the proxy class to annotate custom data for |
Throws | |
---|---|
IOException |
any exception thrown by the underlying OutputStream |
也可以看看:
void drain ()
排除ObjectOutputStream中的任何缓冲数据。 与flush类似,但不会将flush传播到基础流。
Throws | |
---|---|
IOException |
if I/O errors occur while writing to the underlying stream |
boolean enableReplaceObject (boolean enable)
启用流来替换流中的对象。 启用后,将为正在序列化的每个对象调用replaceObject方法。
如果 enable
为真,并且安装了安全管理器,则此方法首先使用 SerializablePermission("enableSubstitution")
权限调用安全管理器的 checkPermission
方法,以确保可以使用流来替换流中的对象。
Parameters | |
---|---|
enable |
boolean : boolean parameter to enable replacement of objects |
Returns | |
---|---|
boolean |
the previous setting before this method was invoked |
Throws | |
---|---|
SecurityException |
if a security manager exists and its checkPermission method denies enabling the stream to do replacement of objects in the stream. |
Object replaceObject (Object obj)
此方法将允许ObjectOutputStream的可信子类在序列化期间将一个对象替换为另一个对象。 在调用enableReplaceObject之前,替换对象将被禁用。 enableReplaceObject方法检查请求进行替换的流是否可信。 写入序列化流的每个对象的第一次出现被传递给replaceObject。 随后对该对象的引用将由原始调用返回给replaceObject的对象替换。 为了确保对象的私有状态不是无意暴露的,只有受信任的流才可以使用replaceObject。
ObjectOutputStream.writeObject方法接受一个Object类型的参数(与Serializable类型相反),以允许不可序列化的对象被可序列化的对象替换。
当一个子类正在替换对象时,它必须确保在反序列化过程中必须进行互补替换,或者替换对象与每个存储引用的字段都兼容。 对象的类型不是字段或数组元素的类型的子类,通过引发异常来中止序列化,并且不存储该对象。
当每个对象第一次遇到时,这个方法只被调用一次。 所有后续对该对象的引用都将被重定向到新对象。 此方法应该返回要替换的对象或原始对象。
可以返回Null作为要替换的对象,但可能会在包含对原始对象的引用的类中导致NullReferenceException,因为它们可能期望一个对象而不是null。
Parameters | |
---|---|
obj |
Object : the object to be replaced |
Returns | |
---|---|
Object |
the alternate object that replaced the specified one |
Throws | |
---|---|
IOException |
Any exception thrown by the underlying OutputStream. |
void writeClassDescriptor (ObjectStreamClass desc)
将指定的类描述符写入ObjectOutputStream。 类描述符用于标识写入流中的对象的类。 ObjectOutputStream的子类可以重写此方法来自定义将类描述符写入序列化流的方式。 然后应该重写ObjectInputStream中的相应方法readClassDescriptor
,以从其自定义流表示中重构类描述符。 默认情况下,此方法根据对象序列化规范中定义的格式写入类描述符。
请注意,只有在ObjectOutputStream未使用旧的序列化流格式时(通过调用ObjectOutputStream的方法useProtocolVersion
设置), useProtocolVersion
调用useProtocolVersion
方法。 如果此序列化流使用旧格式( PROTOCOL_VERSION_1
),则类描述符将以不能被覆盖或定制的方式在内部写入。
Parameters | |
---|---|
desc |
ObjectStreamClass : class descriptor to write to the stream |
Throws | |
---|---|
IOException |
If an I/O error has occurred. |
void writeObjectOverride (Object obj)
子类用于覆盖默认的writeObject方法的方法。 此方法由ObjectInputStream的受信任子类调用,该构造函数使用受保护的无参数构造函数构造ObjectInputStream。 该子类预计会提供修饰符“final”的重写方法。
Parameters | |
---|---|
obj |
Object : object to be written to the underlying stream |
Throws | |
---|---|
IOException |
if there are I/O errors while writing to the underlying stream |
void writeStreamHeader ()
提供了writeStreamHeader方法,以便子类可以将它们自己的头添加或添加到流中。 它将幻数和版本写入流中。
Throws | |
---|---|
IOException |
if I/O errors occur while writing to the underlying stream |