public
class
A
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
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. A
7365 7269 616c 2e41 :com.yln.serial. A
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
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