public class ObjectOutputStream extends OutputStream implements ObjectOutput, ObjectStreamConstants
只有支持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接口的对象的字段。 不可序列化的对象的子类可以是可序列化的。 在这种情况下,非可序列化类必须有一个无参数构造函数,以允许其字段被初始化。 在这种情况下,子类有责任保存并恢复不可序列化类的状态。 通常情况下,该类的字段是可访问的(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最初终止任何现有的块数据记录。
DataOutput
, ObjectInputStream
, Serializable
, Externalizable
, Object Serialization Specification, Section 2, Object Output Classes
Modifier and Type | Class and Description |
---|---|
static class |
ObjectOutputStream.PutField
提供对要写入ObjectOutput的持久字段的编程访问。
|
baseWireHandle, PROTOCOL_VERSION_1, PROTOCOL_VERSION_2, SC_BLOCK_DATA, SC_ENUM, SC_EXTERNALIZABLE, SC_SERIALIZABLE, SC_WRITE_METHOD, 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
Modifier | Constructor and Description |
---|---|
protected |
ObjectOutputStream()
为完全重新实现ObjectOutputStream的子类提供一种方法,不必分配刚刚被ObjectOutputStream实现使用的私有数据。
|
|
ObjectOutputStream(OutputStream out)
创建一个写入指定的OutputStream的ObjectOutputStream。
|
Modifier and Type | Method and Description |
---|---|
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)
写一个字符串作为字节序列。
|
void |
writeChar(int val)
写一个16位的字符。
|
void |
writeChars(String str)
写一个字符串作为一系列的字符。
|
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 。
|
public ObjectOutputStream(OutputStream out) throws IOException
如果安装了一个安全管理器,那么这个构造函数会在被覆盖ObjectOutputStream.putFields或ObjectOutputStream.writeUnshared方法的子类的构造函数直接或间接调用时检查“enableSubclassImplementation”SerializablePermission。
out
- 输出流写入
IOException
- 如果在写入流标题时发生I / O错误
SecurityException
- 如果不可信子类非法覆盖安全敏感方法
NullPointerException
- 如果
out
是
null
ObjectOutputStream()
,
putFields()
,
ObjectInputStream.ObjectInputStream(InputStream)
protected ObjectOutputStream() throws IOException, SecurityException
如果安装了一个安全管理器,此方法首先调用具有SerializablePermission("enableSubclassImplementation")
权限的安全管理器的checkPermission
方法,以确保启用子类化。
SecurityException
- 如果安全管理器存在,并且其
checkPermission
方法拒绝启用子类化。
IOException
- 如果在创建此流时发生I / O错误
SecurityManager.checkPermission(java.security.Permission)
, SerializablePermission
public void useProtocolVersion(int version) throws IOException
此例程提供了一个钩子,以使当前版本的Serialization能够以向后兼容流格式的先前版本的格式写入。
将尽一切努力避免引入额外的后向不兼容性; 然而,有时候别无选择。
version
- 使用java.io.ObjectStreamConstants中的ProtocolVersion。
IllegalStateException
- 如果任何对象被序列化后调用。
IllegalArgumentException
- 如果无效版本传入。
IOException
- 如果发生I / O错误
ObjectStreamConstants.PROTOCOL_VERSION_1
,
ObjectStreamConstants.PROTOCOL_VERSION_2
public final void writeObject(Object obj) throws IOException
对于OutputStream和不应序列化的类的问题,抛出异常。 所有异常对于OutputStream是致命的,它将处于不确定状态,由呼叫者来忽略或恢复流状态。
writeObject
在界面
ObjectOutput
obj
- 要写入的对象
InvalidClassException
- 序列化使用的类错误。
NotSerializableException
- 要序列化的某些对象不实现java.io.Serializable接口。
IOException
- 底层OutputStream抛出的任何异常。
protected void writeObjectOverride(Object obj) throws IOException
obj
- 要写入底层流的对象
IOException
- 如果在写入底层流时存在I / O错误
ObjectOutputStream()
,
writeObject(Object)
public void writeUnshared(Object obj) throws IOException
ObjectOutputStream子类覆盖此方法只能在拥有“enableSubclassImplementation”SerializablePermission的安全上下文中构建; 任何尝试在没有此权限的情况下实例化此类子类将导致抛出SecurityException。
obj
- 对象写入流
NotSerializableException
- 如果要序列化的图中的对象不实现Serializable接口
InvalidClassException
- 如果要序列化的对象的类存在问题
IOException
- 如果在序列化期间发生I / O错误
public void defaultWriteObject() throws IOException
IOException
- 如果在写入底层
OutputStream
时发生I / O错误
public ObjectOutputStream.PutField putFields() throws IOException
IOException
- 如果发生I / O错误
public void writeFields() throws IOException
IOException
- 如果在写入底层流时发生I / O错误
NotActiveException
- 当没有调用类writeObject方法来写入对象的状态时调用。
public void reset() throws IOException
IOException
- 如果在序列化对象时调用了reset()。
protected void annotateClass(类<?> cl) throws IOException
cl
- 用于注释自定义数据的类
IOException
- 底层OutputStream抛出的任何异常。
protected void annotateProxyClass(类<?> cl) throws IOException
对于流中的每个唯一代理类描述符,该方法被称为一次。 这种方法的默认实现ObjectOutputStream
什么都不做。
在相应的方法ObjectInputStream
是resolveProxyClass
。 对于给定的子类ObjectOutputStream
重写该方法中, resolveProxyClass
中的相应子类方法ObjectInputStream
必须读取由写任何数据或对象annotateProxyClass
。
cl
- 用于注释自定义数据的代理类
IOException
-由底层抛出的任何异常
OutputStream
ObjectInputStream.resolveProxyClass(String[])
protected Object replaceObject(Object obj) throws IOException
ObjectOutputStream.writeObject方法接受Object类型的参数(与Serializable类型相反),以允许将非可序列化对象替换为可序列化对象的情况。
当子类替换对象时,必须确保在反序列化期间必须进行补充替换,或者替换对象与要存储引用的每个字段兼容。 类型不是字段或数组元素类型的子类的对象通过引发异常终止序列化,并且不存储该对象。
当首次遇到每个对象时,此方法仅调用一次。 对对象的所有后续引用将被重定向到新对象。 该方法应该返回要替换的对象或原始对象。
Null可以作为要替换的对象返回,但是可能会在包含对原始对象的引用的类中引起NullReferenceException,因为它们可能期望一个对象而不是null。
obj
- 要替换的对象
IOException
- 底层OutputStream抛出的任何异常。
protected boolean enableReplaceObject(boolean enable) throws SecurityException
如果enable
为真,并且安装了一个安全管理器,则该方法首先调用具有SerializablePermission("enableSubstitution")
权限的安全管理器的checkPermission
方法,以确保启用该流来替换流中的对象。
enable
- 用于启用对象更换的布尔参数
SecurityException
- 如果安全管理器存在,并且其
checkPermission
方法拒绝启用流来替换流中的对象。
SecurityManager.checkPermission(java.security.Permission)
, SerializablePermission
protected void writeStreamHeader() throws IOException
IOException
- 如果在写入底层流时发生I / O错误
protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException
readClassDescriptor
中的相应方法,以便从其自定义流表示中重构类描述符。
默认情况下,此方法根据对象序列化规范中定义的格式编写类描述符。
请注意,只有当ObjectOutputStream不使用旧的序列化流格式(通过调用ObjectOutputStream的useProtocolVersion
方法设置)时,才会调用useProtocolVersion
方法。 如果此序列化流使用旧格式( PROTOCOL_VERSION_1
),则类描述符将以不能被覆盖或自定义的方式内部写入。
desc
- 写入流的类描述符
IOException
- 如果发生I / O错误。
ObjectInputStream.readClassDescriptor()
,
useProtocolVersion(int)
,
ObjectStreamConstants.PROTOCOL_VERSION_1
public void write(int val) throws IOException
write
在界面
DataOutput
write
在界面
ObjectOutput
write
在类别
OutputStream
val
-
val
的字节
IOException
- 如果发生I / O错误。
public void write(byte[] buf) throws IOException
write
在界面
DataOutput
write
在界面
ObjectOutput
write
在类别
OutputStream
buf
- 要写入的数据
IOException
- 如果发生I / O错误。
OutputStream.write(byte[], int, int)
public void write(byte[] buf, int off, int len) throws IOException
write
在界面
DataOutput
write
在界面
ObjectOutput
write
在类别
OutputStream
buf
- 要写入的数据
off
- 数据中的起始偏移量
len
- 写入的字节数
IOException
- 如果发生I / O错误。
public void flush() throws IOException
flush
在接口
Flushable
flush
在界面
ObjectOutput
flush
在类别
OutputStream
IOException
- 如果发生I / O错误。
protected void drain() throws IOException
IOException
- 如果在写入底层流时发生I / O错误
public void close() throws IOException
close
在界面
Closeable
close
在界面
ObjectOutput
close
在界面
AutoCloseable
close
在类别
OutputStream
IOException
- 如果发生I / O错误。
public void writeBoolean(boolean val) throws IOException
writeBoolean
在界面
DataOutput
val
- 要写入的布尔值
IOException
- 如果在写入底层流时发生I / O错误
public void writeByte(int val) throws IOException
writeByte
在界面
DataOutput
val
- 要写入的字节值
IOException
- 如果在写入底层流时发生I / O错误
public void writeShort(int val) throws IOException
writeShort
在界面
DataOutput
val
-
val
的短价值
IOException
- 如果在写入底层流时发生I / O错误
public void writeChar(int val) throws IOException
writeChar
在界面
DataOutput
val
- 要写入的char值
IOException
- 如果在写入底层流时发生I / O错误
public void writeInt(int val) throws IOException
writeInt
在界面
DataOutput
val
- 要写入的整数值
IOException
- 如果在写入底层流时发生I / O错误
public void writeLong(long val) throws IOException
writeLong
在界面
DataOutput
val
-
val
的长的价值
IOException
- 如果在写入底层流时发生I / O错误
public void writeFloat(float val) throws IOException
writeFloat
在界面
DataOutput
val
- 要写入的浮点值
IOException
- 如果在写入底层流时发生I / O错误
public void writeDouble(double val) throws IOException
writeDouble
在界面
DataOutput
val
- 要写入的双重值
IOException
- 如果在写入底层流时发生I / O错误
public void writeBytes(String str) throws IOException
writeBytes
在界面
DataOutput
str
- 要写入的字节串
IOException
- 如果在写入底层流时发生I / O错误
public void writeChars(String str) throws IOException
writeChars
在界面
DataOutput
str
- 要写入的字符串
IOException
- 如果在写入底层流时发生I / O错误
public void writeUTF(String str) throws IOException
writeUTF
在界面
DataOutput
str
- 要写入的字符串
IOException
- if I/O errors occur while writing to the underlying stream