ReadObject源码分析01

ReadObject源码分析第一部分

一句话简述流程:
1 通过读取流获得描述对象
2 通过读取class字节码获取描述对象(获取非静态和transient的字段,获取空构造函数并设置可达)
3 过程中获取/计算并判断serialVersionUID时,执行了静态代码块
4 通过反射调取无参构造函数获取实例,然后反射调用它的readobject()方法

传统入口
try (FileInputStream fileIn = new FileInputStream("person.ser");ObjectInput 




 Stream in = new ObjectInputStream(fileIn)) {
        Person deserializedPerson = (Person) in.readObject();
}

F7进入 readObject(Object.class)

F7进入readObject0(type, false)

case匹配Object进入 checkResolve(readOrdinaryObject(unshared));

先F7跟进readOrdinaryObject(unshared),稍后再看checkResolve方法。

F7进入readClassDesc
readClassDesc 方法主要是创建了一个序列化类描述对象,并且从流中获取类的相关信息

F7进入 readNonProxyDesc(unshared)看看都获取了哪些信息

F7进入readClassDescriptor()

这个方法主要是从流的方向获取反序列化类的一些信息。

F7进入desc.readNonProxy方法
从流中读取反序列化类的一些基础信息,比如类名,serialVersionUID,字段名等保存到desc对象中

回到 readNonProxyDesc()继续往下跟,F7进resolveClass(readDesc)

回到 readNonProxyDesc(),F7进入desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false))方法
这个方法主要是从class字节码的方法获取反序列化类的一些信息,并且和前面从流方向获取到的信息做一个汇总。

F7进入lookup(cl, true)
此方法主要是创建一些数据结构,然后从缓存中查找,如果没有就将序列化的类包装到ObjectStreamClass中,并且将这个ObjectStreamClass对象放到缓存中

F7进入 new ObjectStreamClass(cls)
这里主要关注三点,1获取serialVersionUID时调用AccessController.doPrivileged,2获取非静态和非transient 字段,3获取构造函数的方法getSerializableConstructor()

F7进入getDeclaredSUID(cl)
此处通过反射调获取serialVersionUID,会执行动态代码块,如果没有设置serialVersionUID字段,直接返回null

F7进入getSerialFields

然后再F7进入getSerialFields

F7进入getSerializableConstructor()
可以看出获取的时无参构造方法,而且反射设置了setAccessible(true),所以不管是不是public都可以。

返回initNonProxy

当没有显示的手动创建serialVersionUID时,会进入computeDefaultSUID()计算生成。

F7进入computeDefaultSUID()
此方法会根据反序列化对象的一些属性计算hash生成,这里由于会计算静态代码块的相关东西,所以会执行反序列化类的静态代码块


获取到id后,返回继续执行,后边代码是将model和desc中的一些信息赋值给自己的全局变量,model是传入的,是根据流获取的反序列化类的一些属性,desc是我本方法根据class模板获取的对象信息,执行完方法后,返回readNonProxyDesc方法,最终执行完毕,返回desc这个类描述对象

获取到完整的描述对象后,一路return ,返回到 readOrdinaryObject()方法 F7进入desc.newInstance()

执行我们之前设置的无参构造函数的invoke()

F7 进入 readSerialData(obj, desc);
这里只是去执行自订的readobject()方法,执行完后才继续执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值