再次认识java的序列化

首先是我们为什么要序列化?

我们可以来想想游戏的场景,一个游戏有很多关卡,并不是一次性能够打完的。如果我们打完一关,这时候需要退出游戏休息了。当我们再次进入游戏之后发现这个游戏竟然需要重新打起,我们接下来做的第一件事情一定是卸载。。

如何解决上面的问题呢?其实一个游戏会有很多个存档点,当你进入一个存档点之后,就会对之前的进度进行保存。这里提到了保存,那么如何进行保存呢?

这里就延伸到了java的持久化上。java的持久化方式有很多种,比如说数据库,写文件等。这里我们单说序列化,关键为什么是序列化呢,它到底有什么好处呢?对于我来说,其实最大的好处就是简单,只要需要序列化的对象实现了Serializable接口,重点是:序列化接口没有方法或字段!也就是将想要序列化的对象中加入implements
Serializable就可以了,是不是很简单。

序列化过程到底做了什么呢?序列化过程其实就是通过writeObject方法,将对象的数据、状态转化为字节流持久化到文件中。反序列化其实就是通过readObject实现的一个逆过程。

序列化中有几个特殊的点需要注意一下:

第一点是serialVersionUID,java强烈建议在需要序列化的类中显式的声明该值。该值实际上就是起到一个版本号的作用,在解序列化时,会通过该值判断类的版本有没有发生变化。如果发生了变化则在解序列化时会弹出InvalidClassException的错误。为什么呢?因为类的版本变化之后,比如新增了一个属性,或者减少了一个属性。这样在解序列化时肯定会出现错误。

如果不显示的声明serialVersionUID会出现什么问题?如果不显示的声明,序列化运行时将针对该类计算一个默认的serialVersionUID值。默认是怎么计算出来的呢?计算的逻辑在这里逻辑

我们可以看到计算过程还是蛮复杂的,如果你有心情看的话。。。其实里面再次注明了强烈建议显示的指定serialVersionUID。为什么这么强烈的建议呢?存在这样的情况,客户端与服务端架构不同,jvm也不同,当客户端将序列化的对象传递给服务端时,客户端序列化时计算的id与服务端计算的id这时候不一样,这就悲剧了。为了防止悲剧发生,还是手动指定的好

第二点是当一个类中不是所有的属性都需要序列化时怎么办?

这时我们就要用到transient关键字,在定义时做如下处理即可

transient private Integer age

第三点是Externalizable,如果我们觉得Serializable不够灵活,我们可以使用Externalizable。该接口继承于序列化接口并增加了两个方法writeExternal 和 readExternal分别在序列化与反序列化时调用。两方法是用来代替定制的writeObject与readObject方法。想要怎么序列化都靠你自己发挥了

第四点是单例模式下的序列化与反序列化

单例模式就是为了对象的唯一性,我们在序列化与反序列化后就会多出来一个对象,怎么办?

这时候我们就可以用writeReplace 和 readResolve 方法来指派一个替代对象,比如在对象类中增加readResolve方法,该方法直接将单例返回,这样在反序列化时就不会多出来一个对象了。

时间: 2024-11-09 01:01:35

再次认识java的序列化的相关文章

java对象序列化小结

百度百科上介绍序列化是这样的: 序列化 (Serialization): 将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象. 序列化使其他代码可以查看或修改那些不序列化便无法访问的对象实例数据.确切地说,代码执行序列化需要特殊的权限:即指定了 SerializationFormatter 标志的 SecurityPermission.在默认策略下,通过 Internet 下载

Java对象序列化与反序列化

Java对象序列化与反序列化 对象序列化的目标是将对象保存在磁盘中或者在网络中进行传输.实现的机制是允许将对象转为与平台无关的二进制流. java中对象的序列化机制是将允许对象转为字节序列.这些字节序列可以使Java对象脱离程序存在,从而可以保存在磁盘上,也可以在网络间传输. 对象的序列化是将一个Java对象写入IO流:与此对应的,反序列化则是从IO流中恢复一个Java对象. 实现序列化 如果要将一个java对象序列化,那么对象的类需要是可序列化的.要让类可序列化,那么这个类需要实现如下两个接口

【java】理解java对象序列化

关于Java序列化的文章早已是汗牛充栋了,本文是对我个人过往学习,理解及应用Java序列化的一个总结.此文内容涉及Java序列化的基本原理,以及多种方法对序列化形式进行定制.在撰写本文时,既参考了Thinking in Java, Effective Java,JavaWorld,developerWorks中的相关文章和其它网络资料,也加入了自己的实践经验与理解,文.码并茂,希望对大家有所帮助.(2012.02.14最后更新) 1. 什么是Java对象序列化 Java平台允许我们在内存中创建可

JAVA的序列化和持久化的区别与联系

持久化(Persistence) 即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘).持久化的主要应用是将内存中的对象存储在关系型的数据库中,当然也可以存储在磁盘文件中.XML数据文件中等等. 持久化是将程序数据在持久状态和瞬时状态间转换的机制. JDBC就是一种持久化机制.文件IO也是一种持久化机制. 持久化是一种对象服务,就是把内存中的对象保存到外存中,让以后能够取回.需要实现至少3个接口: void Save(object o) 把一个对象保存到外存中 Object Load

深入理解Java对象序列化

关于Java序列化的文章早已是汗牛充栋了,本文是对我个人过往学习,理解及应用Java序列化的一个总结.此文内容涉及Java序列化的基本原理,以及多种方法对序列化形式进行定制.在撰写本文时,既参考了Thinking in Java, Effective Java,JavaWorld,developerWorks中的相关文章和其它网络资料,也加入了自己的实践经验与理解,文.码并茂,希望对大家有所帮助.(持续更新中,2012.02.13最后更新) 1. 什么是Java对象序列化 Java平台允许我们在

Java 的序列化Serializable接口介绍及应用

常看到类中有一串很长的 如 private static final long serialVersionUID = -4667619549931154146L;的数字声明.这些其实是对此类进行序列化的,那为何要进行序列化呢?下面参照网络及jdk说明,进行学习一下: 理解: serialVersionUID 用来表明类的不同版本间的兼容性 简单的说,Java的序列化是通过在运行时判断类的serialversionUID来验证版本的一致性的.在进行序列化时,jvm会把传来的字节流中的serialv

理解Java对象序列化

关于Java序列化的文章早已是汗牛充栋了,本文是对我个人过往学习,理解及应用Java序列化的一个总结.此文内容涉及Java序列化的基本原理,以及多种方法对序列化形式进行定制.在撰写本文时,既参考了Thinking in Java, Effective Java,JavaWorld,developerWorks中的相关文章和其它网络资料,也加入了自己的实践经验与理解,文.码并茂,希望对大家有所帮助.(2012.02.14最后更新) 1. 什么是Java对象序列化 Java平台允许我们在内存中创建可

java对象序列化的理解

1.java中的序列化时transient变量(这个关键字的作用就是告知JAVA我不可以被序列化)和静态变量不会被序列          化(下面是一个测试的例子) (实体带versionUUID,便于反序列化时不会报错.) 2.也是最应该注意的,如果你先序列化对象A后序列化B,那么在反序列化的时候一定记着JAVA规定先读到的对象               是先被序列化的对象,不要先接收对象B,那样会报错.尤其在使用上面的Externalizable的时候一定要注意读取            

Java的序列化与反序列化

Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java序列化与反序列化?本文围绕这些问题进行了探讨. 1.Java序列化与反序列化 Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程. 2.为什么需要序列化与反序列化 我们知道,当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本.图片.音频.视频等, 而这些数据都会以二进制序列的形式在网络上传送.那么当两个Java进程进行通信时,能否实现进程间的对象传送