java.io.ObjectInputStream是实现反序列化的关键类,ObjectInputStream反序列化流,将之前使用 ObjectOutputStream 序列化的原始数据恢复为对象,以流的方式读取对象。其它的用途包括主机之间使用socket流传递对象、远程系统调用。
ObjectInputStream确保从流创建的所有对象的类型与Java虚拟机中的类匹配。类根据需要使用标准机制加载。只能从流中读取实现java.io.Serializable或java.io.Externalizable接口的对象。方法readObject用于从流中读取对象。在Java中,字符串和数组是对象,在序列化期间被视为对象。读取时,需要将它们转换为预期的类型。对象的默认反序列化机制将每个字段的内容还原为写入时的值和类型。反序列化过程将忽略声明为临时或静态的字段。对其他对象的引用会根据需要从流中读取这些对象。使用共享机制可以正确还原对象图。反序列化时总是分配新对象,这会防止现有对象被重写。
ObjectInputStream的构造函数也有两个,从构造函数中可以看出,同样需要验证类的安全性,同时在初始化时会自动读取Java序列化头部信息。跟输出流一样,预留了一个生成全空的类输入流初始化方法,用于继承ObjectInputStream的子类进行重写。安全验证和输出流中是相同的,而读取头部信息需要读取魔术数字和版本号并验证与当前JDK中的是否一致。当然,如果两端使用的JDK中这个类版本号不一致就会出现异常。
public ObjectInputStream(InputStream in) throws IOException {
verifySubclass();
bin = new BlockDataInputStream(in);
handles = new HandleTable(10);
vlist = new ValidationList();
serialFilter = ObjectInputFilter.Config.getSerialFilter();
enableOverride = false;
readStreamHeader();
bin.setBlockDataMode(true);
}
protected ObjectInputStream() throws IOException, SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm