java序列化和反序列化原理,java序列化是什么,如何实现

  java序列化和反序列化原理,java序列化是什么,如何实现

  

前言

关于序列化的几种疑问?

 

  什么是序列化?工作中什么时候用序列化?为什么可以通过实现java.io.Serializable接口来序列化?java里的serialVersionUID为什么不能改?可序列化的序列化和json序列化是什么关系?你知道哪几种深度复制方法?以上问题已经抛出。大家能回答一下吗?如果你不能回答,就继续读下去。

  前提知识:

  在解释之前,扩展一些前提知识。

  00-1010首先我们要知道底层所有的数据传输都是二进制流,这是毋庸置疑的。

  什么是文本协议?什么是二进制协议?

  00-1010文本协议一般是由一串ACSII字符组成的数据,包括数字、大小写字母、百分号、回车(r)、换行符(n)、空格等。

  协议设计的目的是为了方便人们理解,所以通常会在协议中加入一些特殊字符进行分隔。

  比如日常生活中发送请求时常用的XML,JSON xml,JSON,formData。虽然格式不同,但都有一个特点,自带描述信息。

  表单数据31字节

  account=sqrtcatpassword=123456 JSON 41字节

  {account:sqrtcat , password : 123456 } xml字节

  ?xml版本=1.0 编码=UTF-8 ?accountsqrtcat/account password 123456/password但是为了方便解析,文本协议不得不添加一些冗余字符来分隔命令,降低了其传输效率;而且只适合文字传输,很难嵌入其他数据,比如一张图片。

  00-1010二进制协议是一串字节流,通常包括消息头和消息体。消息头的长度是固定的,消息头包括消息体的长度。这样,就可以从数据流中解析出完整的二进制数据。

  二进制协议,没有冗余字段,传输效率高,解析方便(长度固定,字节可以直接比较)。它的缺点是定义死了,什么在哪个位置,它的意义是什么都死了,场景单一。

  

二进制协议和文本协议

首先让百度来解释一下什么是序列化:

 

  序列化是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化过程中,对象将其当前状态写入临时或持久存储区。之后,您可以通过从存储中读取或反序列化对象的状态来重新创建对象。

  那我们工作中什么时候用到序列化了?

  创建Java类时,实现java.io.Serializable接口,通过网络传输或持久化你的对象;

  使用spring annotation @ResponseBody或者json框架(jackson,Gson,fastjson)将json数据返回到前端。

  以上都涉及到序列化。

  为什么实现了java.io.Serializable接口就能序列化?

  Java本身提供了序列化机制,可以将一个对象序列化为二进制形式写入磁盘或输出到网络,将从网络或磁盘读取的字节数组反序列化为一个对象供程序使用。

  就是在java.io包下实现可序列化接口。java对象可以通过使用JDK提供的两个输入和输出流对象ObjectInputStream和ObjectOutputStream进行序列化和反序列化。

  java serialVersionUID之所以不能更改,是为了避免逆序失败,可能抛出序列化运行时异常。

  00-1010在实际工作中,我们会发现我们很少使用java提供的序列化,主要是因为JDK的默认序列化有一些非常严重的缺陷,比如无法实现跨平台、跨语言,也就是说我们用java序列化的对象无法被其他语言或浏览器反序列化。

  为了解决这个问题,通常将Java对象转换成XML或Json格式来实现网络传输。

  

文本协议

看下定义:

 

  JSON (JavaScript Object Notation)是一种轻量级的数据交换格式。它基于ECMAScript(欧洲计算机制造商协会,欧洲

  计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。它和xml一样都是一种数据交换格式。

  我们在后端将需要返回的数据通过json处理成json字符串后转为二进制在网络中传输,浏览器会解析为json字符串,进而我们可以再通过json将json字符串转换为对象。

  json 是⼀种很简洁的协议,但可惜的是,它只能传递基本的数型(int,long,string等),但不能传递byte类型。如果想要传输图⽚等⼆进制⽂件的话,是没办法直接传输。

  json序列化在webapi项目中非常流行。因为json非常的直观明了,调用者能够很直观的知道返回的数据信息。

  二进制序列化一般情况下数据大小会比xml,json的序列化的更小。但是二进制则不能直观的知道数据的内容信息。

  

深拷贝

提供几种Java对象深拷贝方案:

 

  

//1.构造函数 《不推荐》//2.implements Cloneable 重写clone() 《不推荐》//3.序列化后反序列化 《推荐》// 使用Apache Commons Lang序列化进行深拷贝User copyUser = (User) SerializationUtils.clone(user);// 使用Gson序列化进行深拷贝Gson gson = new Gson();User copyUser = gson.fromJson(gson.toJson(user), User.class);// 使用Jackson序列化进行深拷贝ObjectMapper objectMapper = new ObjectMapper();User copyUser = objectMapper.readValue(objectMapper.writeValueAsString(user), User.class);

上面我们可以通过json序列化的方式进行对象深拷贝,下面再提供一种使用二进制序列化的方式进行List<对象>深拷贝的实现方式:

 

  

 public static <T> List<T> copyList(List<T> source) { try { ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(byteOut); out.writeObject(source); ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray()); ObjectInputStream inStream = new ObjectInputStream(byteIn); List<T> list = (List<T>) inStream.readObject(); inStream.close(); byteIn.close(); out.close(); byteOut.close(); return list; } catch (Exception e) { log.info(e.getMessage(), e); } return null; }

到此这篇关于Java序列化原理详解的文章就介绍到这了,更多相关Java序列化 内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

 

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: