一段示例数据:

aced 0005 7372 000b 666f 6f2e 6261 722e
466f 6fff ffff ffff ffff ff02 0002 4900
0361 6765 4c00 046e 616d 6574 0012 4c6a
6176 612f 6c61 6e67 2f53 7472 696e 673b
7870 0000 000a 7400 0374 6f6d

魔数

前 4 个字节是固定的,表示这是通过 JDK 序列化的数据:

  • aced STREAM_MAGIC, 声明使用了序列化协议
  • 0005 STREAM_VERSION, 声明 JDK 序列化协议的版本

序列化对象的类型信息

  • 73 TC_OBJECT, 表示序列化的是一个 Java 对象
  • 72 TC_CLASSDESC, 表示后面是对象的类型信息
  • 000b 表示类名的长度,即 11 字节
  • 66 6f6f 2e62 6172 2e46 6f 接下来 11 字节是类名,即 “foo.bar.Foo”
  • ff ffff ffff ffff ff 类名后的 8 字节是一个长整数,即 serialVersionUID = -1L
  • 02 SC_SERIALIZABLE 标识位,说明这个类实现了 Serializable 接口

对象的字段表

  • 0002 表示这个对象中有 2 个属性
  • 49 即 I, 表示 int,说明这是一个 32 位整数
  • 00 03 表示属性名的长度,即 3 字节
  • 61 6765 即属性名 “age”
  • 4c 即 L, 表示引用类型,说明这个属性是某个类型的引用
  • 00 04 表示属性名的长度,即 4 字节
  • 6e 616d 65 即属性名 “name”
  • 74 TC_STRING 表示后面是个字符串
  • 0012 表示字符串长度,即 18 字节
  • 4c6a 6176 612f 6c61 6e67 2f53 7472 696e 673b 即 “Ljava/lang/String;“

父类信息

  • 78 TC_ENDBLOCKDATA 表示这个数据块到此结束
  • 70 TC_NULL 表示这个类没有父类

如果有父类,则重复第二部分的结构,描述父类信息

对象的属性值

根据第三部分的字段表,可以知道该如何识别属性的值

  1. age, 根据字段表知道它是一个 32 位的整数
    • 0000 000a 即 10
  2. name, 根据类型知道它是一个字符串
    • 74 TC_STRING 表示后面是个字符串
    • 00 03 表示字符串长度为 3
    • 74 6f6d 即 “tom”