- java.lang.Object
-
- java.io.OutputStream
-
- java.io.ObjectOutputStream
-
- 实现的所有接口
-
Closeable
,DataOutput
,Flushable
,ObjectOutput
,ObjectStreamConstants
,AutoCloseable
public class ObjectOutputStream extends OutputStream implements ObjectOutput, ObjectStreamConstants
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方法或使用DataOutput支持的原始数据类型的方法将各个字段写入ObjectOutputStream来保存状态。
序列化不会写出任何未实现java.io.Serializable接口的对象的字段。 不可序列化的对象的子类可以是可序列化的。 在这种情况下,非可序列化类必须具有no-arg构造函数以允许其字段被初始化。 在这种情况下,子类负责保存和恢复非可序列化类的状态。 通常情况下,该类的字段可以访问(公共,包或受保护),或者有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最初会终止任何现有的块数据记录。
- 从以下版本开始:
- 1.1
- 另请参见:
-
DataOutput
,ObjectInputStream
,Serializable
,Externalizable
, Object Serialization Specification, Section 2, Object Output Classes
-
-
嵌套类汇总
嵌套类 变量和类型 类 描述 static class
ObjectOutputStream.PutField
提供对要写入ObjectOutput的持久字段的编程访问。
-
字段汇总
-
Fields declared in interface java.io.ObjectStreamConstants
baseWireHandle, PROTOCOL_VERSION_1, PROTOCOL_VERSION_2, SC_BLOCK_DATA, SC_ENUM, SC_EXTERNALIZABLE, SC_SERIALIZABLE, SC_WRITE_METHOD, SERIAL_FILTER_PERMISSION, STREAM_MAGIC, STREAM_VERSION, SUBCLASS_IMPLEMENTATION_PERMISSION, SUBSTITUTION_PERMISSION, TC_ARRAY, TC_BASE, TC_BLOCKDATA, TC_BLOCKDATALONG, TC_CLASS, TC_CLASSDESC, TC_ENDBLOCKDATA, TC_ENUM, TC_EXCEPTION, TC_LONGSTRING, TC_MAX, TC_NULL, TC_OBJECT, TC_PROXYCLASSDESC, TC_REFERENCE, TC_RESET, TC_STRING
-
-
构造方法摘要
构造方法 变量 构造器 描述 protected
ObjectOutputStream()
为完全重新实现ObjectOutputStream的子类提供一种方法,以便不必分配ObjectOutputStream的此实现刚刚使用的私有数据。ObjectOutputStream(OutputStream out)
创建一个写入指定OutputStream的ObjectOutputStream。
-
方法摘要
所有方法 实例方法 具体的方法 变量和类型 方法 描述 protected void
annotateClass(类<?> cl)
子类可以实现此方法以允许类数据存储在流中。protected void
annotateProxyClass(类<?> cl)
子类可以实现此方法以将流中的自定义数据与动态代理类的描述符一起存储。void
close()
关闭流。void
defaultWriteObject()
将当前类的非静态和非瞬态字段写入此流。protected void
drain()
排除ObjectOutputStream中的所有缓冲数据。protected boolean
enableReplaceObject(boolean enable)
使流能够替换写入流的对象。void
flush()
刷新流。ObjectOutputStream.PutField
putFields()
检索用于缓冲要写入流的持久字段的对象。protected Object
replaceObject(Object obj)
此方法将允许ObjectOutputStream的受信任子类在序列化期间将一个对象替换为另一个对象。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)
将String写为字节序列。void
writeChar(int val)
写一个16位字符。void
writeChars(String str)
将String写为一系列字符。protected void
writeClassDescriptor(ObjectStreamClass desc)
将指定的类描述符写入ObjectOutputStream。void
writeDouble(double val)
写一个64位双。void
writeFields()
将缓冲的字段写入流。void
writeFloat(float val)
写一个32位浮点数。void
writeInt(int val)
写一个32位的int。void
writeLong(long val)
写入64位长。void
writeObject(Object obj)
将指定的对象写入ObjectOutputStream。protected void
writeObjectOverride(Object obj)
子类用于覆盖默认writeObject方法的方法。void
writeShort(int val)
写一个16位的短。protected void
writeStreamHeader()
提供了writeStreamHeader方法,因此子类可以将自己的标头附加或预先添加到流中。void
writeUnshared(Object obj)
将“非共享”对象写入ObjectOutputStream。void
writeUTF(String str)
原始数据以 modified UTF-8格式写入此字符串。-
声明方法的类 java.io.OutputStream
nullOutputStream
-
-
-
-
构造方法详细信息
-
ObjectOutputStream
public ObjectOutputStream(OutputStream out) throws IOException
创建一个写入指定OutputStream的ObjectOutputStream。 此构造函数将序列化流标头写入基础流; 调用者可能希望立即刷新流以确保接收ObjectInputStreams的构造函数在读取头时不会阻塞。如果安装了安全管理器,则此构造函数将在子类的构造函数直接或间接调用时检查“enableSubclassImplementation”SerializablePermission,该构造函数将覆盖ObjectOutputStream.putFields或ObjectOutputStream.writeUnshared方法。
- 参数
-
out
- 要写入的输出流 - 异常
-
IOException
- 如果在写入流标题时发生I / O错误 -
SecurityException
- 如果不受信任的子类非法覆盖安全敏感方法 -
NullPointerException
- 如果out
是null
- 从以下版本开始:
- 1.4
- 另请参见:
-
ObjectOutputStream()
,putFields()
,ObjectInputStream(InputStream)
-
ObjectOutputStream
protected ObjectOutputStream() throws IOException, SecurityException
为完全重新实现ObjectOutputStream的子类提供一种方法,以便不必分配ObjectOutputStream的此实现刚刚使用的私有数据。如果安装了安全管理器,则此方法首先使用
SerializablePermission("enableSubclassImplementation")
权限调用安全管理器的checkPermission
方法,以确保可以启用子类化。- 异常
-
SecurityException
- 如果存在安全管理器且其checkPermission
方法拒绝启用子类化。 -
IOException
- 如果在创建此流时发生I / O错误 - 另请参见:
-
SecurityManager.checkPermission(java.security.Permission)
,SerializablePermission
-
-
方法详细信息
-
useProtocolVersion
public void useProtocolVersion(int version) throws IOException
指定写入流时要使用的流协议版本。此例程提供了一个钩子,以使当前版本的Serialization能够以向后兼容以前版本的流格式的格式进行写入。
我们将尽一切努力避免引入额外的向后兼容性; 然而,有时没有其他选择。
- 参数
-
version
- 使用java.io.ObjectStreamConstants中的ProtocolVersion。 - 异常
-
IllegalStateException
- 如果在序列化任何对象后调用。 -
IllegalArgumentException
- 如果传入的版本无效。 -
IOException
- 如果发生I / O错误 - 从以下版本开始:
- 1.2
- 另请参见:
-
ObjectStreamConstants.PROTOCOL_VERSION_1
,ObjectStreamConstants.PROTOCOL_VERSION_2
-
writeObject
public final void writeObject(Object obj) throws IOException
将指定的对象写入ObjectOutputStream。 写入对象的类,类的签名,以及类的非瞬态和非静态字段及其所有超类型的值。 可以使用writeObject和readObject方法覆盖类的默认序列化。 该对象引用的对象是可传递的,因此可以通过ObjectInputStream重建完整的对象等效图。对于OutputStream和不应序列化的类的问题,会抛出异常。 所有异常对OutputStream都是致命的,而OutputStream处于不确定状态,并且调用者可以忽略或恢复流状态。
- Specified by:
-
writeObject
in interfaceObjectOutput
- 参数
-
obj
- 要写入的对象 - 异常
-
InvalidClassException
- 序列化使用的类有问题。 -
NotSerializableException
- 某些要序列化的对象未实现java.io.Serializable接口。 -
IOException
- 底层OutputStream抛出的任何异常。
-
writeObjectOverride
protected void writeObjectOverride(Object obj) throws IOException
子类用于覆盖默认writeObject方法的方法。 ObjectInputStream的可信子类调用此方法,该子类使用受保护的无参数构造函数构造ObjectInputStream。 期望子类使用修饰符“final”提供覆盖方法。- 参数
-
obj
- 要写入基础流的对象 - 异常
-
IOException
- 如果在写入基础流时存在I / O错误 - 从以下版本开始:
- 1.2
- 另请参见:
-
ObjectOutputStream()
,writeObject(Object)
-
writeUnshared
public void writeUnshared(Object obj) throws IOException
将“非共享”对象写入ObjectOutputStream。 此方法与writeObject相同,只是它始终将给定对象写为流中的新唯一对象(而不是指向先前序列化实例的后引用)。 特别:- 通过writeUnshared写入的对象总是以与新出现的对象(尚未写入流的对象)相同的方式序列化,无论该对象是否先前已写入。
- 如果writeObject用于编写先前使用writeUnshared编写的对象,则先前的writeUnshared操作将被视为写入单独的对象。 换句话说,ObjectOutputStream永远不会生成对通过调用writeUnshared写入的对象数据的反向引用。
覆盖此方法的ObjectOutputStream子类只能在拥有“enableSubclassImplementation”SerializablePermission的安全上下文中构造; 在没有此权限的情况下实例化此类子类的任何尝试都将导致抛出SecurityException。
- 参数
-
obj
- 要写obj
对象 - 异常
-
NotSerializableException
- 如果要序列化的图形中的对象未实现Serializable接口 -
InvalidClassException
- 如果要序列化的对象的类存在问题 -
IOException
- 如果序列化期间发生I / O错误 - 从以下版本开始:
- 1.4
-
defaultWriteObject
public void defaultWriteObject() throws IOException
将当前类的非静态和非瞬态字段写入此流。 这可能只能从被序列化的类的writeObject方法调用。 如果以其他方式调用它,它将抛出NotActiveException。- 异常
-
IOException
- 如果在写入底层OutputStream
发生I / O错误
-
putFields
public ObjectOutputStream.PutField putFields() throws IOException
检索用于缓冲要写入流的持久字段的对象。 调用writeFields方法时,字段将写入流。- 结果
- 包含可序列化字段的Putfield类的实例
- 异常
-
IOException
- 如果发生I / O错误 - 从以下版本开始:
- 1.2
-
writeFields
public void writeFields() throws IOException
将缓冲的字段写入流。- 异常
-
IOException
- 如果在写入基础流时发生I / O错误 -
NotActiveException
- 未调用类writeObject方法时调用以写入对象的状态。 - 从以下版本开始:
- 1.2
-
reset
public void reset() throws IOException
重置将忽略已写入流的任何对象的状态。 状态重置为与新的ObjectOutputStream相同。 流中的当前点被标记为重置,因此相应的ObjectInputStream将在同一点重置。 先前写入流的对象将不会被称为已在流中。 它们将再次写入流中。- 异常
-
IOException
- 如果在序列化对象时调用reset()。
-
annotateClass
protected void annotateClass(类<?> cl) throws IOException
子类可以实现此方法以允许类数据存储在流中。 默认情况下,此方法不执行任 ObjectInputStream中的对应方法是resolveClass。 对于流中的每个唯一类,此方法只调用一次。 类名和签名已经写入流中。 此方法可以自由使用ObjectOutputStream来保存它认为合适的类的任何表示(例如,类文件的字节)。 ObjectInputStream的相应子类中的resolveClass方法必须读取并使用由annotateClass编写的任何数据或对象。- 参数
-
cl
- 为其注释自定义数据的类 - 异常
-
IOException
- 底层OutputStream抛出的任何异常。
-
annotateProxyClass
protected void annotateProxyClass(类<?> cl) throws IOException
子类可以实现此方法以将流中的自定义数据与动态代理类的描述符一起存储。对于流中的每个唯一代理类描述符,此方法只调用一次。
ObjectOutputStream
中此方法的默认实现不执行任何操作。ObjectInputStream
的相应方法是resolveProxyClass
。 对于覆盖此方法的给定子类ObjectOutputStream
,相应子类ObjectInputStream
的resolveProxyClass
方法必须读取annotateProxyClass
写入的任何数据或对象。- 参数
-
cl
- 为其注释自定义数据的代理类 - 异常
-
IOException
- 基础OutputStream
抛出的任何异常 - 从以下版本开始:
- 1.3
- 另请参见:
-
ObjectInputStream.resolveProxyClass(String[])
-
replaceObject
protected Object replaceObject(Object obj) throws IOException
此方法将允许ObjectOutputStream的受信任子类在序列化期间将一个对象替换为另一个对象。 在调用enableReplaceObject之前,将禁用替换对象。 enableReplaceObject方法检查请求进行替换的流是否可信。 写入序列化流的每个对象的第一次出现都传递给replaceObject。 对该对象的后续引用将由对replaceObject的原始调用返回的对象替换。 为确保不会无意中公开对象的私有状态,只有受信任的流可以使用replaceObject。ObjectOutputStream.writeObject方法接受Object类型的参数(与Serializable类型相反),以允许非可序列化对象被可序列化对象替换的情况。
当子类替换对象时,它必须确保在反序列化期间必须进行互补替换,或者替换对象与将存储引用的每个字段兼容。 类型不是字段或数组元素类型的子类的对象通过引发异常来中止序列化,并且不存储该对象。
首次遇到每个对象时,只调用一次此方法。 对该对象的所有后续引用都将重定向到新对象。 此方法应返回要替换的对象或原始对象。
Null可以作为要替换的对象返回,但是可能会在包含对原始对象的引用的类中导致NullReferenceException,因为它们可能期望对象而不是null。
- 参数
-
obj
- 要替换的对象 - 结果
- 替换指定的替换对象
- 异常
-
IOException
- 底层OutputStream抛出的任何异常。
-
enableReplaceObject
protected boolean enableReplaceObject(boolean enable) throws SecurityException
使流能够替换写入流的对象。 启用后,将为每个要序列化的对象调用replaceObject(java.lang.Object)
方法。如果当前未启用对象替换,并且
enable
为true,并且安装了安全管理器,则此方法首先使用SerializablePermission("enableSubstitution")
权限调用安全管理器的checkPermission
方法,以确保允许调用者启用流来替换对象写入流。- 参数
-
enable
- 如果允许对每个被序列化的对象使用replaceObject
,enable
true - 结果
- 调用此方法之前的先前设置
- 异常
-
SecurityException
- 如果存在安全管理器且其checkPermission
方法拒绝启用流来替换写入流的对象。 - 另请参见:
-
SecurityManager.checkPermission(java.security.Permission)
,SerializablePermission
-
writeStreamHeader
protected void writeStreamHeader() throws IOException
提供了writeStreamHeader方法,因此子类可以将自己的标头附加或预先添加到流中。 它将幻数和版本写入流。- 异常
-
IOException
- 如果在写入基础流时发生I / O错误
-
writeClassDescriptor
protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException
将指定的类描述符写入ObjectOutputStream。 类描述符用于标识写入流的对象类。 ObjectOutputStream的子类可以重写此方法,以自定义类描述符写入序列化流的方式。 然后应该重写ObjectInputStream中的相应方法readClassDescriptor
,以从其自定义流表示重构类描述符。 默认情况下,此方法根据对象序列化规范中定义的格式写入类描述符。请注意,仅当ObjectOutputStream未使用旧的序列化流格式(通过调用ObjectOutputStream的
useProtocolVersion
方法设置)时,useProtocolVersion
调用useProtocolVersion
方法。 如果此序列化流使用旧格式(PROTOCOL_VERSION_1
),则类描述符将以无法覆盖或自定义的方式在内部编写。- 参数
-
desc
- 要写desc
类描述符 - 异常
-
IOException
- 如果发生I / O错误。 - 从以下版本开始:
- 1.3
- 另请参见:
-
ObjectInputStream.readClassDescriptor()
,useProtocolVersion(int)
,ObjectStreamConstants.PROTOCOL_VERSION_1
-
write
public void write(int val) throws IOException
写一个字节。 此方法将阻塞,直到实际写入该字节。- Specified by:
-
write
,界面DataOutput
- Specified by:
-
write
,界面ObjectOutput
- Specified by:
-
write
类OutputStream
- 参数
-
val
-val
的字节 - 异常
-
IOException
- 如果发生I / O错误。
-
write
public void write(byte[] buf) throws IOException
写一个字节数组。 此方法将阻塞,直到实际写入字节。- Specified by:
-
write
,界面DataOutput
- Specified by:
-
write
,界面ObjectOutput
- 重写:
-
write
类OutputStream
- 参数
-
buf
- 要写入的数据 - 异常
-
IOException
- 如果发生I / O错误。 - 另请参见:
-
OutputStream.write(byte[], int, int)
-
write
public void write(byte[] buf, int off, int len) throws IOException
写一个子字节数组。- Specified by:
-
write
在界面DataOutput
- Specified by:
-
write
,界面ObjectOutput
- 重写:
-
write
类OutputStream
- 参数
-
buf
- 要写入的数据 -
off
- 数据中的起始偏移量 -
len
- 写入的字节数 - 异常
-
IOException
- 如果发生I / O错误。
-
flush
public void flush() throws IOException
刷新流。 这将写入任何缓冲的输出字节并刷新到底层流。- Specified by:
-
flush
,界面Flushable
- Specified by:
-
flush
,界面ObjectOutput
- 重写:
-
flush
类OutputStream
- 异常
-
IOException
- 如果发生I / O错误。
-
drain
protected void drain() throws IOException
排除ObjectOutputStream中的所有缓冲数据。 与flush类似,但不会将flush传播到底层流。- 异常
-
IOException
- 如果在写入基础流时发生I / O错误
-
close
public void close() throws IOException
关闭流。 必须调用此方法才能释放与该流关联的所有资源。- Specified by:
-
close
,界面AutoCloseable
- Specified by:
-
close
在界面Closeable
- Specified by:
-
close
在界面ObjectOutput
- 重写:
-
close
类OutputStream
- 异常
-
IOException
- 如果发生I / O错误。
-
writeBoolean
public void writeBoolean(boolean val) throws IOException
写一个布尔值。- Specified by:
-
writeBoolean
在界面DataOutput
- 参数
-
val
- 要写入的布尔值 - 异常
-
IOException
- 如果在写入基础流时发生I / O错误
-
writeByte
public void writeByte(int val) throws IOException
写一个8位字节。- Specified by:
-
writeByte
在界面DataOutput
- 参数
-
val
- 要写入的字节值 - 异常
-
IOException
- 如果在写入基础流时发生I / O错误
-
writeShort
public void writeShort(int val) throws IOException
写一个16位的短。- Specified by:
-
writeShort
在界面DataOutput
- 参数
-
val
- 要写入的短值 - 异常
-
IOException
- 如果在写入基础流时发生I / O错误
-
writeChar
public void writeChar(int val) throws IOException
写一个16位字符。- Specified by:
-
writeChar
在界面DataOutput
- 参数
-
val
- 要写入的char值 - 异常
-
IOException
- 如果在写入基础流时发生I / O错误
-
writeInt
public void writeInt(int val) throws IOException
写一个32位的int。- Specified by:
-
writeInt
在界面DataOutput
- 参数
-
val
- 要写入的整数值 - 异常
-
IOException
- 如果在写入基础流时发生I / O错误
-
writeLong
public void writeLong(long val) throws IOException
写入64位长。- Specified by:
-
writeLong
在界面DataOutput
- 参数
-
val
- 要写入的长值 - 异常
-
IOException
- 如果在写入基础流时发生I / O错误
-
writeFloat
public void writeFloat(float val) throws IOException
写一个32位浮点数。- Specified by:
-
writeFloat
in interfaceDataOutput
- 参数
-
val
- 要写入的浮点值 - 异常
-
IOException
- 如果在写入基础流时发生I / O错误
-
writeDouble
public void writeDouble(double val) throws IOException
写一个64位双。- Specified by:
-
writeDouble
,界面DataOutput
- 参数
-
val
- 要写入的double值 - 异常
-
IOException
- 如果在写入基础流时发生I / O错误
-
writeBytes
public void writeBytes(String str) throws IOException
将String写为字节序列。- Specified by:
-
writeBytes
在界面DataOutput
- 参数
-
str
- 要写入的字节串 - 异常
-
IOException
- 如果在写入基础流时发生I / O错误
-
writeChars
public void writeChars(String str) throws IOException
将String写为一系列字符。- Specified by:
-
writeChars
,界面DataOutput
- 参数
-
str
- 要写入的字符串 - 异常
-
IOException
- 如果在写入基础流时发生I / O错误
-
writeUTF
public void writeUTF(String str) throws IOException
该字符串的原始数据以modified UTF-8格式写入。 请注意,将String作为基元数据或作为Object写入流中存在显着差异。 由writeObject编写的String实例最初作为String写入流中。 将来的writeObject()将对字符串的写入引用调用到流中。- Specified by:
-
writeUTF
在界面DataOutput
- 参数
-
str
- 要写入的字符串 - 异常
-
IOException
- if I/O errors occur while writing to the underlying stream
-
-