Java序列化,如何实现序列化和反序列化?常见的序列化协议有哪些?

转自:https://blog.csdn.net/calledWWW/article/details/79307706
阅读:https://blog.csdn.net/wdehxiang/article/details/77872506

一、什么是序列化和反序列化

序列化(Serialization)是一种将对象转化为字节序列的过程;
反序列化(Deserialization)是一种将字节序列重建成一个对象的过程。

二、对象的序列化主要有两种用途

  1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件或数据库中;
比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些session先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。

  2) 在网络上传送对象的字节序列。
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。

三、如何实现序列化

将需要序列化的类实现Serializable接口就可以了,Serializable接口中没有任何方法,可以理解为一个标记,即表明这个类可以序列化。
对象序列化包括如下步骤:
  1) 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;

           ObjectOutputStream out = new ObjectOutputStream(new fileOutputStream(“D:\\objectfile.obj”));
 
 
  • 1

  2) 通过对象输出流的writeObject()方法写对象。

     out.writeObject(“Hello”);
 
 
  • 1

  对象反序列化的步骤如下:
  1) 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;


 
 
  • 1

  2) 通过对象输入流的readObject()方法读取对象。

          String obj1 = (String)in.readObject();
 
 
  • 1

注意事项:
对象的类名、属性会被序列化,方法不会被序列化。
transient修饰的属性和static属性不会被序列化。
要保证需要被序列化的属性也是可序列化的。
反序列化时,需要按照序列化顺序读取相应对象。
进行反序列话的JVM需要拥有序列化对象所属的类的class文件,且文件中的serializableID的值要相同,最好显示声明serializableID的值。

四、serialVersionUID的作用

Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)



常见的序列化协议有哪些
按照http://blog.csdn.net/a837199685/article/details/50611402整理到此处,具体可点击以上链接查看
  • XML
    • 定义
      • XML(Extensible Markup Language)是一种常用的序列化和反序列化协议, 它历史悠久,从1998年的1.0版本被广泛使用至今。
    • 优点
      1. 人机可读性好
      2. 可以指定元素或特性的名称
    • 缺点
      1. 序列化数据只包含数据本身和类的结构,不包括类型标识和程序集信息。
      2. 类必须有一个将由 XmlSerializer 序列化的默认构造函数。
      3. 只能序列化公共属性和字段,不能序列化方法。
      4. 文件庞大,文件格式复杂,传输占带宽
    • 使用场景
      1. 当作配置文件存储数据
      2. 实时数据转换
  • json(JavaScript Object Notation, JS 对象标记)
    • 定义
      • JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。它基于 ECMAScript (w3c制定的js规范)的一个子集, JSON采用与编程语言无关的文本格式,但是也使用了类C语言(包括C, C++, C#, Java, JavaScript, Perl, Python等)的习惯,简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
    • 优点
      1. 前后兼容性高。
      2. 数据格式比较简单,易于读写。
      3. 序列化后数据较小,可扩展性好,兼容性好。
      4. 与XML相比,其协议比较简单,解析速度比较快。
    • 缺点
      1. 数据的描述性比XML差。
      2. 不适合性能要求为ms级别的情况。
      3. 额外空间开销比较大。
    • 使用场景
      1. 跨防火墙访问。
      2. 可调试性要求高的情况。
      3. 基于Web browser的Ajax请求。
      4. 传输数据量较小,实时性要求低(例如秒级别)的服务
  • Fastjson
    • 定义
      • Fastjson是一个Java语言编写的高性能功能完善的JSON库。它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致。
    • 优点
      1. 接口简单易用。
      2. 目前Java中最快的json库。
    • 缺点
      1. 过于注重快,而偏离了“标准”及功能性。
      2. 代码质量不高,文档不全
    • 使用场景
      1. 协议交互。
      2. 文件输出。
      3. Android客户端。
  • Thrift
    • 定义
      • Thrift并不仅仅是序列化协议,而是一个RPC框架。它可以让你选择客户端与服务端之间传输通信协议的类别,即文本(text)和二进制(binary)传输协议, 为节约带宽,提供传输效率,一般情况下使用二进制类型的传输协议。
    • 优点
      1. 序列化后的体积小, 速度快。
      2. 支持多种语言和丰富的数据类型。
      3. 对于数据字段的增删具有较强的兼容性。
      4. 支持二进制压缩编码。
    • 缺点
      1. 使用者较少。
      2. 跨防火墙访问时,不安全。
      3. 不具有可读性,调试代码时相对困难。
      4. 不能与其他传输层协议共同使用(例如HTTP)。
      5. 无法支持向持久层直接读写数据,即不适合做数据持久化序列化协议。
    • 使用场景
      1. 分布式系统的RPC解决方案
  • Avro
    • 定义
      • Avro属于Apache Hadoop的一个子项目。 Avro提供两种序列化格式:JSON格式或者Binary格式。Binary格式在空间开销和解析性能方面可以和Protobuf媲美,Avro的产生解决了JSON的冗长和没有IDL的问题。
    • 优点
      1. 支持丰富的数据类型。
      2. 简单的动态语言结合功能。
      3. 具有自我描述属性。
      4. 提高了数据解析速度。
      5. 快速可压缩的二进制数据形式。
      6. 可以实现远程过程调用RPC。
      7. 支持跨编程语言实现。
    • 缺点
      1. 对于习惯于静态类型语言的用户不直观
    • 使用场景
      1. 在Hadoop中做Hive、Pig和MapReduce的持久化数据格式
  • Protobuf
    • 定义
      • protocol buffers 由谷歌开源而来,在谷歌内部久经考验。它将数据结构以.proto文件进行描述,通过代码生成工具可以生成对应数据结构的POJO对象和Protobuf相关的方法和属性。
    • 优点
      1. 序列化后码流小,性能高。
      2. 结构化数据存储格式(XML JSON等)。
      3. 通过标识字段的顺序,可以实现协议的前向兼容。
      4. 结构化的文档更容易管理和维护。
    • 缺点
      1. 需要依赖于工具生成代码。
      2. 支持的语言相对较少,官方只支持Java 、C++ 、Python。
    • 使用场景
      1. 对性能要求高的RPC调用。
      2. 具有良好的跨防火墙的访问属性。
      3. 适合应用层对象的持久化。
  • 其他
    1. protostuff 基于protobuf协议,但不需要配置proto文件,直接导包即可。
    2. Jboss marshaling 可以直接序列化java类, 无须实java.io.Serializable接口。
    3. Message pack 一个高效的二进制序列化格式。
    4. Hessian 采用二进制协议的轻量级remoting onhttp工具。
    5. kryo 基于protobuf协议,只支持java语言,需要注册(Registration),然后序列化(Output),反序列化(Input)。


为什么java序列化接口没有方法却可以完成序列化

Serializable是一个所谓的标记接口,也就是说,实现这个接口是给这个类贴个标签,说它是Serializable的就可以了,具体实现是由JVM内部实现的,这个标签实际上是告诉JVM,你可以将我序列化。但这个标签不是随便贴的,如果你给一个类贴了这个标签,却在内部用到没贴这个标签的类,那运行时就可能有异常抛出。标记接口的用法现在一般被Annotation代替了,但Serializable是在Annotation还没出现前就存在了的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值