(资料图片)
首先上github项目地址(基本可以直接将go struct直接与java class互转,觉得可以的大家给颗星)https://github.com/qauzy/huskyhttps://github.com/qauzy/husky项目源于GitHub - davidwang2007/golang-java-serializer: golang library for handle java serialization/deserializationgolang library for handle java serialization/deserialization - GitHub - davidwang2007/golang-java-serializer: golang library for handle java serialization/deserializationhttps://github.com/davidwang2007/golang-java-serializer
Java序列化算法:
java的序列化算法看起来比较简单,
1 首先是序列化文件头,接着是类描述符,接着父类的描述符(如果存在),直至没有父类。
2 接着是数据部分,从父类的成员数据开始,如果成员数据是Object类型还需要先写入该Object类的描述符,接着才是数据
3 对于ArrayList,HashMap等类型自带了序列化方法,需要执行特殊序列化
具体过程可以看下面github中例子的解析过程第一部分是序列化文件头0xACED: magic 声明使用了序列化协议. 0x05: version 序列化协议版本. 0x73: TC_OBJECT. 声明这是一个新的对象.按顺序获取类描述,类数据块信息,获取第[0]块信息 第二部分是序列化的类的描述[深度:0]0x72: TC_CLASSDESC. 声明这里开始一个新Class 0x21: 类名字的长度[33] 0x636F6D2E6578616D706C652E64656D6F2E6D6F64656C2E55736572456E74697479: 尝试读取类名[com.example.demo.model.UserEntity] 0x48B027EB0BF53976: SerialVersionUID,序列化ID,如果没有指定,则会由算法随机生成一个8byte的ID. [添加] [引用] [0] 类型:TC_CLASSDESC[0x72], refVal:{"ClassName":"com.example.demo.model.UserEntity","ScFlag":0,"SerialVersionUID":5237730257103305078,"Fields":null,"RwDatas":null} 0x02: 标记号. 该值声明该对象支持序列化 0x08: 该类[com.example.demo.model.UserEntity]所包含的域个数,有8个成员第三部分是类[com.example.demo.model.UserEntity]中各个属性的描述 准备解析类[com.example.demo.model.UserEntity]第1个属性0x4C: 成员类型[L] 0x05: 成员名字长度 0x6769667473: 成员名字[gifts] 0x74: TC_STRING.如果成员类型是对象,则后面跟着一个该对象的类名 0x15: 该TC_STRING的长度[21] 0x4C6A6176612F7574696C2F41727261794C6973743B: 字符串原文:Ljava/util/ArrayList; [添加] [引用] [1] 类型:TC_STRING[0x74], refVal:"Ljava/util/ArrayList;" 类[com.example.demo.model.UserEntity]第1个属性 :type: 0x4C, name: gifts, flag: 0x2, class: Ljava/util/ArrayList;准备解析类[com.example.demo.model.UserEntity]第2个属性0x5B: 成员类型[[] 0x06: 成员名字长度 0x676966747332: 成员名字[gifts2] 0x74: TC_STRING.如果成员类型是对象,则后面跟着一个该对象的类名 0x13: 该TC_STRING的长度[19] 0x5B4C6A6176612F6C616E672F537472696E673B: 字符串原文:[Ljava/lang/String; [添加] [引用] [2] 类型:TC_STRING[0x74], refVal:"[Ljava/lang/String;" 类[com.example.demo.model.UserEntity]第2个属性 :type: 0x5B, name: gifts2, flag: 0x2, class: [Ljava/lang/String;准备解析类[com.example.demo.model.UserEntity]第3个属性0x4C: 成员类型[L] 0x02: 成员名字长度 0x6964: 成员名字[id] 0x74: TC_STRING.如果成员类型是对象,则后面跟着一个该对象的类名 0x10: 该TC_STRING的长度[16] 0x4C6A6176612F6C616E672F4C6F6E673B: 字符串原文:Ljava/lang/Long; [添加] [引用] [3] 类型:TC_STRING[0x74], refVal:"Ljava/lang/Long;" 类[com.example.demo.model.UserEntity]第3个属性 :type: 0x4C, name: id, flag: 0x2, class: Ljava/lang/Long;准备解析类[com.example.demo.model.UserEntity]第4个属性0x4C: 成员类型[L] 0x06: 成员名字长度 0x6F7468657273: 成员名字[others] 0x74: TC_STRING.如果成员类型是对象,则后面跟着一个该对象的类名 0x13: 该TC_STRING的长度[19] 0x4C6A6176612F7574696C2F486173684D61703B: 字符串原文:Ljava/util/HashMap; [添加] [引用] [4] 类型:TC_STRING[0x74], refVal:"Ljava/util/HashMap;" 类[com.example.demo.model.UserEntity]第4个属性 :type: 0x4C, name: others, flag: 0x2, class: Ljava/util/HashMap;准备解析类[com.example.demo.model.UserEntity]第5个属性0x4C: 成员类型[L] 0x07: 成员名字长度 0x6F746865727332: 成员名字[others2] 0x71: TC_REFERENCE 标识引用 0x7E0004: TC_REFERENCE引用序号[4] 类[com.example.demo.model.UserEntity]第5个属性 :type: 0x4C, name: others2, flag: 0x2, class: Ljava/util/HashMap;准备解析类[com.example.demo.model.UserEntity]第6个属性0x4C: 成员类型[L] 0x03: 成员名字长度 0x736F6E: 成员名字[son] 0x74: TC_STRING.如果成员类型是对象,则后面跟着一个该对象的类名 0x22: 该TC_STRING的长度[34] 0x4C636F6D2F6578616D706C652F64656D6F2F6D6F64656C2F536F6E456E746974793B: 字符串原文:Lcom/example/demo/model/SonEntity; [添加] [引用] [5] 类型:TC_STRING[0x74], refVal:"Lcom/example/demo/model/SonEntity;" 类[com.example.demo.model.UserEntity]第6个属性 :type: 0x4C, name: son, flag: 0x2, class: Lcom/example/demo/model/SonEntity;准备解析类[com.example.demo.model.UserEntity]第7个属性0x4C: 成员类型[L] 0x08: 成员名字长度 0x757365724E616D65: 成员名字[userName] 0x74: TC_STRING.如果成员类型是对象,则后面跟着一个该对象的类名 0x12: 该TC_STRING的长度[18] 0x4C6A6176612F6C616E672F537472696E673B: 字符串原文:Ljava/lang/String; [添加] [引用] [6] 类型:TC_STRING[0x74], refVal:"Ljava/lang/String;" 类[com.example.demo.model.UserEntity]第7个属性 :type: 0x4C, name: userName, flag: 0x2, class: Ljava/lang/String;准备解析类[com.example.demo.model.UserEntity]第8个属性0x4C: 成员类型[L] 0x07: 成员名字长度 0x75736572536578: 成员名字[userSex] 0x71: TC_REFERENCE 标识引用 0x7E0006: TC_REFERENCE引用序号[6] 类[com.example.demo.model.UserEntity]第8个属性 :type: 0x4C, name: userSex, flag: 0x2, class: Ljava/lang/String;0x78: TC_ENDBLOCKDATA,在readObject中,表明数据已经读取完毕按顺序获取类描述,类数据块信息,获取第[1]块信息 第四部分为对象的父类信息描述 第二部分是序列化的类的描述[深度:1]0x72: TC_CLASSDESC. 声明这里开始一个新Class 0x21: 类名字的长度[33] 0x636F6D2E6578616D706C652E64656D6F2E6D6F64656C2E42617365456E74697479: 尝试读取类名[com.example.demo.model.BaseEntity] 0x01: SerialVersionUID,序列化ID,如果没有指定,则会由算法随机生成一个8byte的ID. [添加] [引用] [7] 类型:TC_CLASSDESC[0x72], refVal:{"ClassName":"com.example.demo.model.BaseEntity","ScFlag":0,"SerialVersionUID":1,"Fields":null,"RwDatas":null} 0x02: 标记号. 该值声明该对象支持序列化 0x01: 该类[com.example.demo.model.BaseEntity]所包含的域个数,有1个成员第三部分是类[com.example.demo.model.BaseEntity]中各个属性的描述 准备解析类[com.example.demo.model.BaseEntity]第1个属性0x4C: 成员类型[L] 0x08: 成员名字长度 0x626173654E616D65: 成员名字[baseName] 0x71: TC_REFERENCE 标识引用 0x7E0006: TC_REFERENCE引用序号[6] 类[com.example.demo.model.BaseEntity]第1个属性 :type: 0x4C, name: baseName, flag: 0x2, class: Ljava/lang/String; 0x78: TC_ENDBLOCKDATA,在readObject中,表明数据已经读取完毕按顺序获取类描述,类数据块信息,获取第[2]块信息 0x70: TC_NULL,标记后面的数据为空,説明已经没有父类信息了[深度:2][添加] [引用] [8] 类型:TC_OBJECT[0x73], refVal:{"Classes":[{"ClassName":"com.example.demo.model.UserEntity","ScFlag":2,"SerialVersionUID":5237730257103305078,"Fields":[{"FieldType":76, "FieldName":"gifts","FieldOwnerScFlag":2,"FieldObjectClassName":"Ljava/util/ArrayList;","FieldValue":null},{"FieldType":91,"FieldName":"gifts2","FieldOwnerScFlag":2,"FieldObjectClassNa me":"[Ljava/lang/String;","FieldValue":null},{"FieldType":76,"FieldName":"id","FieldOwnerScFlag":2,"FieldObjectClassName":"Ljava/lang/Long;","FieldValue":null},{"FieldType":76,"FieldNa me":"others","FieldOwnerScFlag":2,"FieldObjectClassName":"Ljava/util/HashMap;","FieldValue":null},{"FieldType":76,"FieldName":"others2","FieldOwnerScFlag":2,"FieldObjectClassName":"Lja va/util/HashMap;","FieldValue":null},{"FieldType":76,"FieldName":"son","FieldOwnerScFlag":2,"FieldObjectClassName":"Lcom/example/demo/model/SonEntity;","FieldValue":null},{"FieldType": 76,"FieldName":"userName","FieldOwnerScFlag":2,"FieldObjectClassName":"Ljava/lang/String;","FieldValue":null},{"FieldType":76,"FieldName":"userSex","FieldOwnerScFlag":2,"FieldObjectCla ssName":"Ljava/lang/String;","FieldValue":null}],"RwDatas":null},{"ClassName":"com.example.demo.model.BaseEntity","ScFlag":2,"SerialVersionUID":1,"Fields":[{"FieldType":76,"FieldName": "baseName","FieldOwnerScFlag":2,"FieldObjectClassName":"Ljava/lang/String;","FieldValue":null}],"RwDatas":null}],"SerialVersionUID":0,"JsonData":null,"RawData":null}第五部分数据信息(类成员值),从父类的Field反序列化[com.example.demo.model.UserEntity] 第五部分数据信息(类成员值),从父类的Field反序列化[com.example.demo.model.BaseEntity]->分解动作 尝试获取第[1]个类(可序列化)[com.example.demo.model.BaseEntity]-->第[0]个成员[baseName]值************************BEGIN[baseName]************************解析对象类型类成员[baseName]0x74: TC_STRING.如果成员类型是对象,则后面跟着一个该对象的类名 0x04: 该TC_STRING的长度[4] 0x62617365: 字符串原文:base [添加] [引用] [9] 类型:TC_STRING[0x74], refVal:"base"************************END[baseName]************************ 第五部分数据信息(类成员值),从父类的Field反序列化[com.example.demo.model.UserEntity]->分解动作 尝试获取第[0]个类(可序列化)[com.example.demo.model.UserEntity]-->第[0]个成员[gifts]值 ************************BEGIN[gifts]************************解析对象类型类成员[gifts] [ReadTcObjFieldValue]解析类对象0x73: TC_OBJECT. 声明这是一个新的对象(未被消费)按顺序获取类描述,类数据块信息,获取第[0]块信息 第二部分是序列化的类的描述[深度:0]0x72: TC_CLASSDESC. 声明这里开始一个新Class 0x13: 类名字的长度[19] 0x6A6176612E7574696C2E41727261794C697374: 尝试读取类名[java.util.ArrayList] 0x7881D21D99C7619D: SerialVersionUID,序列化ID,如果没有指定,则会由算法随机生成一个8byte的ID. [添加] [引用] [10] 类型:TC_CLASSDESC[0x72], refVal:{"ClassName":"java.util.ArrayList","ScFlag":0,"SerialVersionUID":8683452581122892189,"Fields":null,"RwDatas":null} 0x03: 标记号. 拥有自己的writeObject, readObject, for example: HashMap, 此种类型需要每一个定义一个相应的结构体 0x01: 该类[java.util.ArrayList]所包含的域个数,有1个成员第三部分是类[java.util.ArrayList]中各个属性的描述 准备解析类[java.util.ArrayList]第1个属性0x49: 成员类型[I] 0x04: 成员名字长度 0x73697A65: 成员名字[size] 类[java.util.ArrayList]第1个属性 :type: 0x49, name: size, flag: 0x3, class: 0x78: TC_ENDBLOCKDATA,在readObject中,表明数据已经读取完毕按顺序获取类描述,类数据块信息,获取第[1]块信息0x70: TC_NULL,标记后面的数据为空,説明已经没有父类信息了[深度:1] [添加] [引用] [11] 类型:TC_OBJECT[0x73], refVal:{"Classes":[{"ClassName":"java.util.ArrayList","ScFlag":3,"SerialVersionUID":8683452581122892189,"Fields":[{"FieldType":73,"FieldName":" size","FieldOwnerScFlag":3,"FieldObjectClassName":"","FieldValue":null}],"RwDatas":null}],"SerialVersionUID":0,"JsonData":null,"RawData":null}第五部分数据信息(类成员值),从父类的Field反序列化[java.util.ArrayList]第五部分数据信息(类成员值),从父类的Field反序列化[java.util.ArrayList]->分解动作 尝试获取第[0]个类(自定义序列化)[java.util.ArrayList] ************************BEGIN************************ [JavaArrayList] >> =================Blockdata数据块起始位置=================0x04: Blockdata数据块大小[4] 0x77: 在对象的WriteObject方法中,我们可以自定义的写入数据,除了非Object数据,其他所有数据将会被写在一起,也就是BlockData 0x04: 固定为0x04 0x04: 数组元素的个数======================读取第1个数据块====================== 0x74: TC_STRING.代表一个new String.用String来引用对象(ReadNextEle) [添加] [引用] [12] 类型:TC_STRING[0x74], refVal:"AAAAA" ======================读取第2个数据块====================== 0x71: TC_REFERENCE 0x7E000C: TC_REFERENCE引用序号[12] ======================读取第3个数据块====================== 0x74: TC_STRING.代表一个new String.用String来引用对象(ReadNextEle) [添加] [引用] [13] 类型:TC_STRING[0x74], refVal:"BBBBB" ======================读取第4个数据块====================== 0x71: TC_REFERENCE 0x7E000D: TC_REFERENCE引用序号[13] 0x78: TC_ENDBLOCKDATA,在readObject中,表明数据已经读取完毕[JavaArrayList] << ************************END************************ ************************END[gifts]************************尝试获取第[0]个类(可序列化)[com.example.demo.model.UserEntity]-->第[1]个成员[gifts2]值 ************************BEGIN[gifts2]************************ 解析数组类型类成员[gifts2]0x13: 类名字的长度[19] 0x5B4C6A6176612E6C616E672E537472696E673B: 尝试读取类名[[Ljava.lang.String;] 0xADD256E7E91D7B47: SerialVersionUID,序列化ID,如果没有指定,则会由算法随机生成一个8byte的ID. [添加] [引用] [14] 类型:TC_CLASSDESC[0x72], refVal:{"ClassName":"[Ljava.lang.String;","ScFlag":0,"SerialVersionUID":12525169067719228231,"Fields":null,"RwDatas":null} 0x02: 标记号. 该值声明该对象支持序列化 0x00: 该类[[Ljava.lang.String;]所包含的域个数,有0个成员第三部分是类[[Ljava.lang.String;]中各个属性的描述0x78: TC_ENDBLOCKDATA,在readObject中,表明数据已经读取完毕 [添加] [引用] [15] 类型:TC_ARRAY[0x75], refVal:{"ClassDesc":{"ClassName":"[Ljava.lang.String;","ScFlag":2,"SerialVersionUID":12525169067719228231,"Fields":[],"RwDatas":null},"SerialVer sionUID":12525169067719228231,"Values":null,"JsonData":null} 0x70: TC_NULL,标记后面的数据为空,对应java就是Null 0x74: TC_STRING.如果成员类型是对象,则后面跟着一个该对象的类名 0x06: 该TC_STRING的长度[6] 0x313131313131: 字符串原文:111111 [添加] [引用] [16] 类型:TC_STRING[0x74], refVal:"111111" 0x74: TC_STRING.如果成员类型是对象,则后面跟着一个该对象的类名 0x07: 该TC_STRING的长度[7] 0x33333333333333: 字符串原文:3333333 [添加] [引用] [17] 类型:TC_STRING[0x74], refVal:"3333333" 0x74: TC_STRING.如果成员类型是对象,则后面跟着一个该对象的类名 0x0A: 该TC_STRING的长度[10] 0x34343434343434343434: 字符串原文:4444444444 [添加] [引用] [18] 类型:TC_STRING[0x74], refVal:"4444444444"************************END[gifts2]************************ 尝试获取第[0]个类(可序列化)[com.example.demo.model.UserEntity]-->第[2]个成员[id]值 ************************BEGIN[id]************************ 解析对象类型类成员[id] [ReadTcObjFieldValue]解析类对象0x73: TC_OBJECT. 声明这是一个新的对象(未被消费)按顺序获取类描述,类数据块信息,获取第[0]块信息 第二部分是序列化的类的描述[深度:0]0x72: TC_CLASSDESC. 声明这里开始一个新Class 0x0E: 类名字的长度[14] 0x6A6176612E6C616E672E4C6F6E67: 尝试读取类名[java.lang.Long] 0x3B8BE490CC8F23DF: SerialVersionUID,序列化ID,如果没有指定,则会由算法随机生成一个8byte的ID. [添加] [引用] [19] 类型:TC_CLASSDESC[0x72], refVal:{"ClassName":"java.lang.Long","ScFlag":0,"SerialVersionUID":4290774380558885855,"Fields":null,"RwDatas":null}0x02: 标记号. 该值声明该对象支持序列化 0x01: 该类[java.lang.Long]所包含的域个数,有1个成员第三部分是类[java.lang.Long]中各个属性的描述 准备解析类[java.lang.Long]第1个属性0x4A: 成员类型[J] 0x05: 成员名字长度 0x76616C7565: 成员名字[value] 类[java.lang.Long]第1个属性 :type: 0x4A, name: value, flag: 0x2, class: 0x78: TC_ENDBLOCKDATA,在readObject中,表明数据已经读取完毕按顺序获取类描述,类数据块信息,获取第[1]块信息 第四部分为对象的父类信息描述 第二部分是序列化的类的描述[深度:1]0x72: TC_CLASSDESC. 声明这里开始一个新Class 0x10: 类名字的长度[16] 0x6A6176612E6C616E672E4E756D626572: 尝试读取类名[java.lang.Number] 0x86AC951D0B94E08B: SerialVersionUID,序列化ID,如果没有指定,则会由算法随机生成一个8byte的ID. [添加] [引用] [20] 类型:TC_CLASSDESC[0x72], refVal:{"ClassName":"java.lang.Number","ScFlag":0,"SerialVersionUID":9704295249057472651,"Fields":null,"RwDatas":null} 0x02: 标记号. 该值声明该对象支持序列化 0x00: 该类[java.lang.Number]所包含的域个数,有0个成员 第三部分是类[java.lang.Number]中各个属性的描述 0x78: TC_ENDBLOCKDATA,在readObject中,表明数据已经读取完毕按顺序获取类描述,类数据块信息,获取第[2]块信息0x70: TC_NULL,标记后面的数据为空,説明已经没有父类信息了[深度:2] [添加] [引用] [21] 类型:TC_OBJECT[0x73], refVal:{"Classes":[{"ClassName":"java.lang.Long","ScFlag":2,"SerialVersionUID":4290774380558885855,"Fields":[{"FieldType":74,"FieldName":"value ","FieldOwnerScFlag":2,"FieldObjectClassName":"","FieldValue":null}],"RwDatas":null},{"ClassName":"java.lang.Number","ScFlag":2,"SerialVersionUID":9704295249057472651,"Fields":[],"RwDa tas":null}],"SerialVersionUID":0,"JsonData":null,"RawData":null}第五部分数据信息(类成员值),从父类的Field反序列化[java.lang.Long] 第五部分数据信息(类成员值),从父类的Field反序列化[java.lang.Number]->分解动作 第五部分数据信息(类成员值),从父类的Field反序列化[java.lang.Long]->分解动作 尝试获取第[0]个类(可序列化)[java.lang.Long]-->第[0]个成员[value]值 ************************BEGIN[value]************************0x01: 解析原生类型成员值 1************************END[value]************************ ************************END[id]************************ 尝试获取第[0]个类(可序列化)[com.example.demo.model.UserEntity]-->第[3]个成员[others]值 ************************BEGIN[others]************************ 解析对象类型类成员[others] [ReadTcObjFieldValue]解析类对象0x73: TC_OBJECT. 声明这是一个新的对象(未被消费)按顺序获取类描述,类数据块信息,获取第[0]块信息 第二部分是序列化的类的描述[深度:0]0x72: TC_CLASSDESC. 声明这里开始一个新Class 0x11: 类名字的长度[17] 0x6A6176612E7574696C2E486173684D6170: 尝试读取类名[java.util.HashMap] 0x507DAC1C31660D1: SerialVersionUID,序列化ID,如果没有指定,则会由算法随机生成一个8byte的ID. [添加] [引用] [22] 类型:TC_CLASSDESC[0x72], refVal:{"ClassName":"java.util.HashMap","ScFlag":0,"SerialVersionUID":362498820763181265,"Fields":null,"RwDatas":null} 0x03: 标记号. 拥有自己的writeObject, readObject, for example: HashMap, 此种类型需要每一个定义一个相应的结构体 0x02: 该类[java.util.HashMap]所包含的域个数,有2个成员第三部分是类[java.util.HashMap]中各个属性的描述准备解析类[java.util.HashMap]第1个属性 0x46: 成员类型[F]0x0A: 成员名字长度 0x6C6F6164466163746F72: 成员名字[loadFactor] 类[java.util.HashMap]第1个属性 :type: 0x46, name: loadFactor, flag: 0x3, class:准备解析类[java.util.HashMap]第2个属性0x49: 成员类型[I] 0x09: 成员名字长度 0x7468726573686F6C64: 成员名字[threshold] 类[java.util.HashMap]第2个属性 :type: 0x49, name: threshold, flag: 0x3, class: 0x78: TC_ENDBLOCKDATA,在readObject中,表明数据已经读取完毕按顺序获取类描述,类数据块信息,获取第[1]块信息0x70: TC_NULL,标记后面的数据为空,説明已经没有父类信息了[深度:1] [添加] [引用] [23] 类型:TC_OBJECT[0x73], refVal:{"Classes":[{"ClassName":"java.util.HashMap","ScFlag":3,"SerialVersionUID":362498820763181265,"Fields":[{"FieldType":70,"FieldName":"loa dFactor","FieldOwnerScFlag":3,"FieldObjectClassName":"","FieldValue":null},{"FieldType":73,"FieldName":"threshold","FieldOwnerScFlag":3,"FieldObjectClassName":"","FieldValue":null}],"R wDatas":null}],"SerialVersionUID":0,"JsonData":null,"RawData":null}第五部分数据信息(类成员值),从父类的Field反序列化[java.util.HashMap] 第五部分数据信息(类成员值),从父类的Field反序列化[java.util.HashMap]->分解动作 尝试获取第[0]个类(自定义序列化)[java.util.HashMap] ************************BEGIN************************ [JavaHashMap] has 0.000000 buckest [JavaHashMap] has 0 mappings(size)0x74: TC_STRING.代表一个new String.用String来引用对象(ReadNextEle) [添加] [引用] [24] 类型:TC_STRING[0x74], refVal:"1qqqq" 0x71: TC_REFERENCE 0x7E0018: TC_REFERENCE引用序号[24] 0x74: TC_STRING.代表一个new String.用String来引用对象(ReadNextEle) [添加] [引用] [25] 类型:TC_STRING[0x74], refVal:"4rrrr" 0x71: TC_REFERENCE 0x7E0019: TC_REFERENCE引用序号[25] 0x74: TC_STRING.代表一个new String.用String来引用对象(ReadNextEle) [添加] [引用] [26] 类型:TC_STRING[0x74], refVal:"2wwww" 0x71: TC_REFERENCE 0x7E001A: TC_REFERENCE引用序号[26] 0x74: TC_STRING.代表一个new String.用String来引用对象(ReadNextEle) [添加] [引用] [27] 类型:TC_STRING[0x74], refVal:"3eeee" 0x71: TC_REFERENCE 0x7E001B: TC_REFERENCE引用序号[27] 0x78: TC_ENDBLOCKDATA,在readObject中,表明数据已经读取完毕************************END************************ ************************END[others]************************ 尝试获取第[0]个类(可序列化)[com.example.demo.model.UserEntity]-->第[4]个成员[others2]值 ************************BEGIN[others2]************************ 解析对象类型类成员[others2] [ReadTcObjFieldValue]解析类对象0x73: TC_OBJECT. 声明这是一个新的对象(未被消费)按顺序获取类描述,类数据块信息,获取第[0]块信息0x71: TC_REFERENCE 标识引用 0x7E0016: TC_REFERENCE引用序号[22](OBJECT-->TC_CLASSDESC)--> java.util.HashMap [添加] [引用] [28] 类型:TC_OBJECT[0x73], refVal:{"Classes":[{"ClassName":"java.util.HashMap","ScFlag":3,"SerialVersionUID":362498820763181265,"Fields":[{"FieldType":70,"FieldName":"loa dFactor","FieldOwnerScFlag":3,"FieldObjectClassName":"","FieldValue":null},{"FieldType":73,"FieldName":"threshold","FieldOwnerScFlag":3,"FieldObjectClassName":"","FieldValue":null}],"R wDatas":[{"ClassDesc":null,"LoadFactor":0.75,"Thredshold":12,"Buckets":16,"Entries":{"1qqqq":"1qqqq","2wwww":"2wwww","3eeee":"3eeee","4rrrr":"4rrrr"}}]}],"SerialVersionUID":0,"JsonData ":null,"RawData":null}第五部分数据信息(类成员值),从父类的Field反序列化[java.util.HashMap] 第五部分数据信息(类成员值),从父类的Field反序列化[java.util.HashMap]->分解动作 尝试获取第[0]个类(自定义序列化)[java.util.HashMap] ************************BEGIN************************ [JavaHashMap] has 0.000000 buckest [JavaHashMap] has 0 mappings(size)0x74: TC_STRING.代表一个new String.用String来引用对象(ReadNextEle) [添加] [引用] [29] 类型:TC_STRING[0x74], refVal:"1tttt" 0x71: TC_REFERENCE 0x7E001D: TC_REFERENCE引用序号[29] 0x78: TC_ENDBLOCKDATA,在readObject中,表明数据已经读取完毕************************END************************ ************************END[others2]************************ 尝试获取第[0]个类(可序列化)[com.example.demo.model.UserEntity]-->第[5]个成员[son]值 ************************BEGIN[son]************************ 解析对象类型类成员[son] [ReadTcObjFieldValue]解析类对象 0x73: TC_OBJECT. 声明这是一个新的对象(未被消费) 按顺序获取类描述,类数据块信息,获取第[0]块信息 第二部分是序列化的类的描述[深度:0]0x72: TC_CLASSDESC. 声明这里开始一个新Class 0x20: 类名字的长度[32] 0x636F6D2E6578616D706C652E64656D6F2E6D6F64656C2E536F6E456E74697479: 尝试读取类名[com.example.demo.model.SonEntity] 0x01: SerialVersionUID,序列化ID,如果没有指定,则会由算法随机生成一个8byte的ID. [添加] [引用] [30] 类型:TC_CLASSDESC[0x72], refVal:{"ClassName":"com.example.demo.model.SonEntity","ScFlag":0,"SerialVersionUID":1,"Fields":null,"RwDatas":null} 0x02: 标记号. 该值声明该对象支持序列化 0x01: 该类[com.example.demo.model.SonEntity]所包含的域个数,有1个成员第三部分是类[com.example.demo.model.SonEntity]中各个属性的描述 准备解析类[com.example.demo.model.SonEntity]第1个属性0x4C: 成员类型[L] 0x07: 成员名字长度 0x536F6E4E616D65: 成员名字[SonName] 0x71: TC_REFERENCE 标识引用 0x7E0006: TC_REFERENCE引用序号[6] 类[com.example.demo.model.SonEntity]第1个属性 :type: 0x4C, name: SonName, flag: 0x2, class: Ljava/lang/String; 0x78: TC_ENDBLOCKDATA,在readObject中,表明数据已经读取完毕按顺序获取类描述,类数据块信息,获取第[1]块信息0x70: TC_NULL,标记后面的数据为空,説明已经没有父类信息了[深度:1] [添加] [引用] [31] 类型:TC_OBJECT[0x73], refVal:{"Classes":[{"ClassName":"com.example.demo.model.SonEntity","ScFlag":2,"SerialVersionUID":1,"Fields":[{"FieldType":76,"FieldName":"SonNa me","FieldOwnerScFlag":2,"FieldObjectClassName":"Ljava/lang/String;","FieldValue":null}],"RwDatas":null}],"SerialVersionUID":0,"JsonData":null,"RawData":null}第五部分数据信息(类成员值),从父类的Field反序列化[com.example.demo.model.SonEntity] 第五部分数据信息(类成员值),从父类的Field反序列化[com.example.demo.model.SonEntity]->分解动作 尝试获取第[0]个类(可序列化)[com.example.demo.model.SonEntity]-->第[0]个成员[SonName]值 ************************BEGIN[SonName]************************ 解析对象类型类成员[SonName]0x74: TC_STRING.如果成员类型是对象,则后面跟着一个该对象的类名 0x13: 该TC_STRING的长度[19] 0x5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A5A: 字符串原文:ZZZZZZZZZZZZZZZZZZZ [添加] [引用] [32] 类型:TC_STRING[0x74], refVal:"ZZZZZZZZZZZZZZZZZZZ"************************END[SonName]************************ ************************END[son]************************ 尝试获取第[0]个类(可序列化)[com.example.demo.model.UserEntity]-->第[6]个成员[userName]值 ************************BEGIN[userName]************************ 解析对象类型类成员[userName]0x74: TC_STRING.如果成员类型是对象,则后面跟着一个该对象的类名 0x07: 该TC_STRING的长度[7] 0x31313131313131: 字符串原文:1111111 [添加] [引用] [33] 类型:TC_STRING[0x74], refVal:"1111111"************************END[userName]************************ 尝试获取第[0]个类(可序列化)[com.example.demo.model.UserEntity]-->第[7]个成员[userSex]值 ************************BEGIN[userSex]************************ 解析对象类型类成员[userSex]0x74: TC_STRING.如果成员类型是对象,则后面跟着一个该对象的类名 0x0E: 该TC_STRING的长度[14] 0x3232323232323232326461736464: 字符串原文:222222222dasdd [添加] [引用] [34] 类型:TC_STRING[0x74], refVal:"222222222dasdd"