java 序列化(serialization)算法的透露

声明
[quote]原文出处:http://www.javaworld.com/community/node/2915
Submitted by javatips on Thu, 05/07/2009 - 15:28
[/quote]
序列化是将对象状态保存到字节队列的过程。
反序列化是:将这些字节队列转换为一个活生生对象的过程。java 序列化的api为开发者处理序列化提供了一套标准的方法。在这个话题中,你将看到将怎么去序列化一个对象。为什么有时候序列化是必须的呢?你将学习到序列化算法在java中的应用,紧接着你将看到一个被编排序列化的并且有插图的对象。你到目前为至你应该对序列化算法的工作和实体被序列化(作为对象的一部分)有一点了解吧

[b]为什么序列化是必须的[/b]
在今天的这个世界上,一个有代表性的公司有很多各种各样的组件,在分布式系统之间和网络之间交互。在java中一切都由对象来表示,如果java中的两个组件之间想互相交流,需要一种方法去交换数据,第一种方法是定义你的协议去转换对象,意思就是接受者根据这条协议知道这是发送者创建的对象,若是第三个组件加入进来就比较困难了。因此这儿需要一个通用的并且效率高组件之间的对象转换协议,序列化的定义就是为了这个目的,java组件就是用这个协议来实现对象之间的转换。
图一:显示了一个客户端和服务器端之间交流高级视图,这有一个通过序列化实现客户端到服务器端对象之间的转换。[img]http://www.javaworld.com/javaworld/jw-05-2009/images/jtip050709-fig1.gif[/img]

[b]怎么去序列化一个对象[/b]
目的是序列化一个对象,首先你要确定类对象实现了java.io.Serializable借口如下列表

Listing 1. Implementing Serializable
class TestSerial implements Serializable {
public byte version = 100;
public byte count = 0;
}

在listing1中你必须做的不同的是创建一个实现java.io.Serializable接口的正常类。这个接口就是一个标记性借口哦,此接口断言根本没有任何方法,表明实现此接口的类将被序列化。

现在你已经创建了一个合格并且序列化的类,下一步是真正的去序列化这个对象,那就是调用java.io.ObjectOutputStream类的writeObject()方法,如下listing2
Listing 2. Calling writeObject()

public static void main(String args[]) throws IOException {
FileOutputStream fos = new FileOutputStream("temp.out");
ObjectOutputStream oos = new ObjectOutputStream(fos);
TestSerial ts = new TestSerial();
oos.writeObject(ts);
oos.flush();
oos.close();
}


在一个文件中listing2中存储的TestSerial 对象状态,被temp.out.oos.writeObject(ts);方法调用,实际上是踢出了序列化算法,这个算法循环把对象写到temp.out
在序列化文件里面重新创建对象,你需要雇用以下listing3的代码
Listing 3 recreating a serialized object

public static void main(String args[]) throws IOException {
FileInputStream fis = new FileInputStream("temp.out");
ObjectInputStream oin = new ObjectInputStream(fis);
TestSerial ts = (TestSerial) oin.readObject();
System.out.println("version="+ts.version);
}

在listing3 中调用oin.readObject();方法,对象的原型就会被复原,这个方法读取我们先前创建活生生元素对象的复制品的对象的字节,因为readObject()能够读取任何序列化对象,一个塑造对象的类型是必要的。执行这段代码将在控制台输出version=100;

[b]一个序列化格式的对象[/b]
序列化形式的对象看起来像什么呢?回忆一下,在前面段落的简单代码保存了序列化形式的TestSerial的对象到temp.out。listing 4显示了temp.out的内容,十六进制显示(你需要一个十六进制的编辑器去查看这些输出的十六进制)
listing 4 TestSerial对象的十六进制形式如下:

AC ED 00 05 73 72 00 0A 53 65 72 69 61 6C 54 6573 74 A0 0C 34 00 FE B1 DD F9 02 00 02 42 00 0563 6F 75 6E 74 42 00 07 76 65 72 73 69 6F 6E 7870 00 64


如果你不太喜欢真实的TestSerial对象,那你就看只有两种类型的数字,listing 5 如下

  public byte version = 100;	
public byte count = 0;


一个byte类型变量的大小是 1 byte,因此总大小是2个字节,不过你要是在listing 4 中看序列化对象的大小的话,那就是51个字节。令人惊讶的是这些额外的字节是在那里来的,他们存在的意义又是什么,他们是通过序列化算法生产出来的额,目的就是重新创建对象,在接下里的章节,你认真研究一下这些细节中的算法

[b]java 序列化算法[/b]

到目前为之你应该对对怎么去序列化一个对象有了一个很好的了解,那这个过程是怎么进行的?如下是一个通用的序列化算法。
1.它写出了类对象内部的元数据
2、它递归地写出了从超级类到java.lang.Object 的描述。
3、一旦到它写完了元数据的信息,紧接着它就启动关联实例的真实数据,不过在此时,它的启动来源与最顶层的超级类。
4、它就会去写关联这个实例的数据,从最小的超类到最大获得类


[size=medium][b]翻译中。。。。。。。。。。。。。。[/b][/size]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值