- ObjectInputStream反序列化原始数据和先前使用ObjectOutputStream写入的对象。
- 当分别与FileOutputStream和FileInputStream一起使用时,ObjectOutputStream和ObjectInputStream可以为应用程序提供对象图的持久存储。
- ObjectInputStream用于恢复以前序列化的那些对象。其他用途包括使用套接字流在主机之间传递对象,或在远程通信系统中用于编组和解组参数和参数。
- ObjectInputStream确保从流创建的图中的所有对象的类型与Java虚拟机中存在的类匹配。使用标准机制根据需要加载类。
- 只能从流中读取支持java.io.Serializable或java.io.Externalizable接口的对象。
- readObject方法用于从流中读取对象。应该使用Java的安全转换来获取所需的类型。在Java中,字符串和数组是对象,在序列化期间被视为对象。
- 读取时,需要将其强制转换为预期的类型。可以使用DataInput上的适当方法从流中读取原始数据类型。
- 对象的默认反序列化机制将每个字段的内容还原为写入时具有的值和类型。反序列化过程将忽略声明为瞬态或静态的字段。对其他对象的引用会导致根据需要从流中读取这些对象。使用引用共享机制可以正确还原对象图。
- 反序列化时始终分配新对象,以防止现有对象被覆盖。读取对象类似于运行新对象的构造函数。
- 为该对象分配了内存,并将其初始化为零(NULL)。为不可序列化的类调用无参数构造函数,然后从流中恢复可序列化类的字段,从最接近java.lang.object的可序列化类开始,最后以对象的最特定类结束。
FileInputStream fis = new FileInputStream("t.tmp"); ObjectInputStream ois = new ObjectInputStream(fis);
int i = ois.readInt(); String today = (String) ois.readObject(); Date date = (Date) ois.readObject(); ois.close();
readObject方法负责使用通过相应的writeObject方法写入流中的数据读取和还原其特定类的对象状态。该方法无需将自身与属于其超类或子类的状态相关。通过从ObjectInputStream读取各个字段的数据并分配给对象的相应字段来恢复状态。 DataInput支持读取原始数据类型。
任何尝试读取对象数据的尝试都超出了由相应的writeObject方法写入的自定义数据的范围,则将引发eData字段值为true的OptionalDataException。超出分配数据末尾的非对象读取将以指示数据流结束的相同方式反映数据的结束:按字节读取将返回-1作为读取的字节或读取的字节数,并且原始读取将引发EOFExceptions。如果没有相应的writeObject方法,则默认序列化数据的结尾将标记分配的数据的结尾。
从readExternal方法内发出的原始和对象读取调用的行为方式相同-如果流已经位于相应的writeExternal方法写入的数据的末尾,则对象读取将抛出OptionalDataExceptions且eof设置为true,按字节读取将返回-1,原始读取将抛出EOFExceptions。请注意,此行为不适用于使用旧的ObjectStreamConstants.PROTOCOL_VERSION_1协议编写的流,在该协议中,未区分由writeExternal方法编写的数据结尾,因此无法检测到。
如果序列化流未将给定类列出为要反序列化的对象的超类,则readObjectNoData方法负责为其特定类初始化对象的状态。在接收方使用与发送方不同的反序列化实例类的版本,并且接收方的版本扩展了发送方版本未扩展的类的情况下,可能会发生这种情况。如果序列化流已被篡改,也会发生这种情况。因此,尽管源流“敌对”或不完整,但readObjectNoData对于正确初始化反序列化的对象很有用。
序列化不会读取任何值或将值分配给任何未实现java.io.Serializable接口的对象。不可序列化的对象的子类可以被序列化。在这种情况下,不可序列化的类必须具有no-arg构造函数,以允许对其字段进行初始化。在这种情况下,子类负责保存和恢复不可序列化类的状态。通常,该类的字段是可访问的(公共,程序包或受保护),或者存在可用于还原状态的get和set方法。
反序列化对象时发生的任何异常都将被ObjectInputStream捕获并中止读取过程。
实现Externalizable接口使对象可以完全控制对象序列化表单的内容和格式。调用Externalizable接口的方法writeExternal和readExternal来保存和恢复对象状态。当由类实现时,它们可以使用ObjectOutput和ObjectInput的所有方法来写入和读取自己的状态。对象负责处理发生的任何版本控制。
枚举常量的反序列化方式与普通可序列化或可外部化的对象不同。枚举常量的序列化形式仅由其名称组成;常量的字段值不发送。为了反序列化一个枚举常量,ObjectInputStream从流中读取常量名称。然后,通过以枚举常量的基本类型和接收到的常量名称作为参数的静态方法Enum.valueOf(Class,String)来获取反序列化的常量。像其他可序列化或可外部化的对象一样,枚举常量可以用作随后出现在序列化流中的反向引用的目标。无法自定义反序列化枚举常量的过程:反序列化期间,将忽略由枚举类型定义的任何特定于类的readObject,readObjectNoData和readResolve方法。同样,任何serialPersistentFields或serialVersionUID字段声明也将被忽略-所有枚举类型的固定serialVersionUID为0L。
构造函数
- ObjectInputStream()
- ObjectInputStream(InputStream in)
方法
- void defaultReadObject(),从此流中读取当前类的非静态和非瞬态字段
- protected boolean enableResolveObject(boolean enable),启用流以允许替换从流读取的对象 读取一个布尔值
- boolean readBoolean(),读取一个布尔值
- byte readByte(),读取一个8位字节
- char readChar(),读取一个16位的字符
- protected ObjectStreamClass readClassDescriptor(),从序列化流中读取类描述符
- double readDouble(),读取一个64位双精度浮点
- ObjectInputStream.GetField readFields(),从流中读取持久字段,并使它们按名称可用
- float readFloat(),读取一个32位的浮点
- void readFully(byte[] buf),读取字节,阻塞直到读取所有字节
- void readFully(byte[] buf, int off, int len),读取字节,阻塞直到读取所有字节
- int readInt(),读取32位的整型
- String readLine(),此方法不能正确将字节转换为字符
- long readLong(),读取一个64位long型
- Object readObject(),从输入流中读取一个object
- protected Object readObjectOverride(),由使用受保护的无参数构造函数构造ObjectOutputStream的ObjectOutputStream的受信任子类调用此方法
- short readShort(),读取16位短整型
- protected voide readStreamHeader(),提供了readStreamHeader方法,以允许子类读取和验证其自己的流头
- Object readUnshared(),从ObjectInputStream读取“非共享”对象
- int readUnsignedShort(),读取一个16位无符号短整型
- String readUTF(),读取修改后的UTF-8格式的字符串
- void registerValidation(ObjectInputValidation obj, int prio),在返回图形之前,注册要验证的对象
- protected Class<?> resolveClass(ObjectStreamClass desc),加载与指定的流类描述等效的本地类
- protected Object resolveObject(Object obj),此方法将允许ObjectInputStream的受信任子类在反序列化期间将一个对象替换为另一个对象
- protected Class<?> resolveProxyClass(String[] interfaces),返回实现在代理类描述符中命名的接口的代理类; 子类可以实现此方法以从流中读取自定义数据以及动态代理类的描述符,从而允许它们为接口和代理类使用备用加载机制