Java 序列化 格式

public   class   implements   Serializable {
       private   static   final   long   serialVersionUID   = 1L;
       public   byte   version   = 100;
       public   static   void   main(String[] args)   throws   IOException {
            ObjectOutputStream out =   new   ObjectOutputStream(   new   FileOutputStream(
                           "result.obj" ));
            Atest =   new   A();
               // 试图将对象两次写入文件
            out.writeObject(test);
            out.close();
      }
}
上面类序列化后文件如下:
aced 0005 7372 0010 636f 6d2e 796c 6e2e
7365 7269 616c 2e41 0000 0000 0000 0001
0200 0142 0007 7665 7273 696f 6e78 7064

AC ED    固定的2个字节的魔术字
00  05   序列化协议版本
73: TC_OBJECT. 声明这是一个新的对象

输出相关类的描述。
0x72: TC_CLASSDESC. 声明这里开始一个新 Class 。
0010: 类名长度,包含包名
636f 6d2e 796c 6e2e
7365 7269 616c 2e41 :com.yln.serial.
0000 0000 0000 0001: 8字节的 SerialVersionUID , 序列化 ID ,如果没有指定,则会由算法随机生成一个 8byte 的 ID
02: 标记号.该值声明该对象支持序列化
00 01: 该类所包含的字段个数
接下来,输出其中的一个字段:
42: 表示 B,代表Byte,其余类型有:
                                'B' // byte
                                'C' // char
                                'D' // double
                                'F' // float
                                'I' // integer
                                'J' // long
                                'S' // short
                                'Z' // boolean
00 07: 域名字的长度
76 65 72 73 69 6F 6E: version, 域名字描述

0x78: TC_ENDBLOCKDATA,对象块结束的标志。
0x70: TC_NULL,没有超类了。

输出域的值信息:
00: 域值为00
64: 域值为100

来看下复杂的例子
public   class   Contain   implements   Serializable{
       private   static   final   long   serialVersionUID   = 1L;
       public   byte   version   = 100;
}
public   class   Parent   implements   Serializable{
       private   static   final   long   serialVersionUID   = 1L;
       public   byte   version   = 100;
}
public   class   ComplexSerialFormat   extends   Parent   implements   Serializable {
       private   static   final   long   serialVersionUID   = 1L;
       public   byte   version   = 100;
       public   Contain   cont   =   new   Contain();
       public   static   void   main(String[] args)   throws   FileNotFoundException, IOException {
               //   TODO   Auto-generated method stub
            ObjectOutputStream out =   new   ObjectOutputStream(   new   FileOutputStream(
                           "complex.obj" ));
            ComplexSerialFormat test =   new   ComplexSerialFormat();
            out.writeObject(test);
            out.close();
      }
}
aced 0005 7372 0022 636f 6d2e 796c 6e2e
7365 7269 616c 2e43 6f6d 706c 6578 5365
7269 616c 466f 726d 6174 0000 0000 0000
0001 0200 0242 0007 7665 7273 696f 6e4c
0004 636f 6e74 7400 184c 636f 6d2f 796c
6e2f 7365 7269 616c 2f43 6f6e 7461 696e
3b78 7200 1563 6f6d 2e79 6c6e 2e73 6572
6961 6c2e 5061 7265 6e74 0000 0000 0000
0001 0200 0142 0007 7665 7273 696f 6e78
7064 6473 7200 1663 6f6d 2e79 6c6e 2e73
6572 6961 6c2e 436f 6e74 6169 6e00 0000
0000 0000 0102 0001 4200 0776 6572 7369
6f6e 7870 64

AC ED: STREAM_MAGIC. 声明使用了序列化协议
00  05: STREAM_VERSION. 序列化协议版本
0x73: TC_OBJECT. 声明这是一个新的对象
输出相关类的描述。
0x72: TC_CLASSDESC. 声明这里开始一个新 Class 。
0022:类名长度,包含包名
636f 6d2e 796c 6e2e 7365 7269 616c 2e43 6f6d 706c 6578 5365 7269 616c 466f 726d 6174  :  com.yln.serial. ComplexSerialFormat
0000 0000 0000 0001 : 8字节的 SerialVersionUID , 序列化 ID
02: 标记号.该值声明该对象支持序列化
00 02: 该类所包含的字段个数
42:表示 B,代表Byte,其余类型有:
                                'B' // byte
                                'C' // char
                                'D' // double
                                'F' // float
                                'I' // integer
                                'J' // long
                                'S' // short
                                'Z' // boolean
00 07: 域名字的长度
76 65 72 73 69 6F 6E: version, 域名字描述

输出下一个域,contain con = new contain();这个有点特殊,是个对象。描述对象类型引用时需要使用JVM的标准对象签名表示法 
0x4C: 域的类型
0004: 域名字长度
636f 6e74: 域名字  cont
0x74: TC_STRING. 代表一个new String.用String来引用对象
00 18:该String长度
4c 636f 6d2f 796c 6e2f 7365 7269 616c 2f43 6f6e 7461 696e 3b: Lcom/yl/serial/contain; JVM的标准对象签名表示法
0x78: TC_ENDBLOCKDATA,对象数据块结束的标志

输出超类也就是Parent类描述了
0x72: TC_CLASSDESC. 声明这个是个新类
00 15: 类名长度
63 6f6d 2e79 6c6e 2e73 6572 6961 6c2e 5061 7265 6e74:com.yln.serial. Parent
0000 0000 0000 0001:8字节的 SerialVersionUID , 序列化 ID
02: 标记号.该值声明该对象支持序列化
00 01: 该类所包含的字段个数
42:表示 B,代表Byte,其余类型有:
                                'B' // byte
                                'C' // char
                                'D' // double
                                'F' // float
                                'I' // integer
                                'J' // long
                                'S' // short
                                'Z' // boolean
00 07: 域名字的长度
76 65 72 73 69 6F 6E: version, 域名字描述
0x78: TC_ENDBLOCKDATA,对象块结束的标志;
0x70: TC_NULL, 说明没有其他超类的标志

下一步就是把实例对象的实际值输出了。这时候是从parent Class的域开始的
64 :  parent中 version值
64:   ComplexSerialFormat 中值

再往后的bytes比较有意思,算法需要描述contain类的信息,要记住,现在还没有对contain类进行过描述
73 TC_OBJECT, 声明这是一个新的对象
72 TC_CLASSDESC声明这里开始一个新Class
00 16 类名的长度
63 6f6d 2e79 6c6e 2e73 6572 6961 6c2e 436f 6e 74 6169 6e :contain,类名描述;
00 0000 0000 0000 01:8字节的 SerialVersionUID , 序列化 ID
02: 标记号.该值声明该对象支持序列化
00 01:该类所包含的字段个数
42:表示 B,代表Byte,其余类型有:
                                'B' // byte
                                'C' // char
                                'D' // double
                                'F' // float
                                'I' // integer
                                'J' // long
                                'S' // short
                                'Z' // boolean
00 07: 域名字的长度
76 65 72 73 69 6F 6E: version, 域名字描述
0x78: TC_ENDBLOCKDATA,对象块结束的标志。
0x70: TC_NULL,没有超类了。
输出域的值信息:
00: 域值为00
64: 域值为100



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值