前言

关于序列化的几种疑问?

  • 什么是序列化?工作中什么时候用到序列化了?
  • 为什么实现了java.io.Serializable接口就能序列化?
  • java中serialVersionUID 为什么不能改变?
  • Serializable序列化和json序列化有什么关系?
  • 你都会哪几种对象深拷贝方式?

以上抛出了几个问题,大家都能回答上来吗?回答不上来的话就接着往下看吧。

前提知识:

讲解之前先扩充一些前提知识。

二进制协议和文本协议

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

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

文本协议

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

文本协议设计的目的就是方便人们理解、读懂,所以,协议中通常会加入一些特殊字符用于分隔。

比如日常中发送请求时经常用到的方式: xmljsonformData,他们虽然格式不同,但都有一个特征,自带描述信息。

formData 31bytes

account=sqrtcat&password=123456

json 41bytes

{"account":"sqrtcat","password":"123456"}

xml 94bytes

<?xml version="1.0" encoding="UTF-8" ?> <account>sqrtcat</account> <password>123456</password>

但为了便于解析,文本协议不得不添加一些冗余的字符用于分隔命令,降低了其传输的效率;而且只适于传输文本,很难嵌入其他数据,比如一张图片。

二进制协议

二进制协议就是一串字节流,通常包括消息头(header)和消息体(body),消息头的长度固定,并且消息头包括了消息体的长度。这样就能够从数据流中解析出一个完整的二进制数据。

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

序列化

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

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

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

在创建一个Java类时实现java.io.Serializable接口,将你的对象进行网络传输或者持久化;

使用spring注解@ResponseBody或者使用JSON框架(jackson、Gson、fastjson)等给前端返回json数据。

以上都涉及到了序列化。

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

Java自己提供了一种序列化机制,这种机制能将一个对象序列化成二进制形式,用于写入磁盘或输出到网络,同时将从网络或者磁盘中读取的字节数组,反序列化成对象,在程序中使用。

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

java中serialVersionUID 不能改变的原因是避免反序列失败,可能会抛出序列化运行时异常。

Java序列化缺陷

实际工作中会发现我们自己很少会使用java提供的序列化,主要是因为JDK默认的序列化存在着一些非常严重的缺陷,比如它是无法实现跨平台和跨语言的,意思是我们在java中序列化的对象是无法被其他语言或者是被浏览器反序列的。

为了解决这一问题通常将Java对象转换为XML或Json格式进而实现网络传输。

JSON

看下定义:

JSON(JavaScript Object Notation, JS对象简谱)是一种轻量级的数据交换格式。它基于 ECMAScript(European Computer Manufacturers Association, 欧洲计算机协会制定的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序列化 内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

Java序列化原理详解的更多相关文章

  1. ios – CGPath和UIBezierPath()有什么区别?

    目前,我正在努力制作一个自定义按钮,我有一个图像,并具有坐标,但我发现您可以通过使用CGPath类或UIBezierPath创建一个按钮/对象类.有人可以告诉我两者有什么区别?解决方法CGPath是CoreGraphics库的不透明类型,而UIBezierPath是UIKit中的Obj-C类.UIBezierPath是一个围绕CGPath的包装,具有更加面向对象的界面和一些方便的方法.使用CGPath可能会略微更快,因为它不必经过Obj-C,并且它具有更高级的功能,如CGPathApply.重要的是,UI

  2. swift 快速奔跑的兔几 本节的内容是:序列化与反序列化

    在cocoa中,我们经常需要向磁盘保存数据块,cocoa将这些数据块表示为NSData对象例如,有一个字符串,将其转换为NSData,可以使用如下方法:我们还可以将对象转化为数据。遵守协议NSCoding的对象可以转换为NSData对象,也可以从NSData对象中加载,方法如下:

  3. Swift中一个类中的枚举enum类型的数据该如何实现序列化NSCoder

    简述昨天在开发中遇到了这样一个问题,需要用NSUserDefaults持久化一些数据,其中需要保存一个自己定义的类对象。结束其实枚举本来就是一个Int,因此我们将其声明为Int型就可以根据Int值初始化了,以此实现序列化和反序列化。

  4. swift json的序列化和反序列化

    还有一点东西没写完,权作笔记参考:http://www.hangge.com/blog/cache/detail_983.html

  5. Swift中对象序列化的实现

    Swift中对象序列化的实现在swift中要使某个类可以序列化,只需要类实现NSCoding协议,并实现协议中的一个必要的构造函数和一个方法,分别对应序列化和反序列化的二个过程。

  6. Alamofire 4.0 迁移指南

    原文:Alamofire4.0MigrationGuide作者:cnoon译者:kemchenj译者注:最近打算把公司项目迁移到Swift3.0,顺手把Alamofire4.0的迁移指南翻译了,之前虽然读过一部分源码,但还是看到了很多新东西,新的Adapter和Retrier我都打算用到项目里,希望大家看完也能够有收获.Alamofire4.0是Alamofire最新的一个大版本更新,一个基于Sw

  7. [HandyJSON] 在Swift语言中处理JSON - 转换JSON和Model

    而HandyJSON是其中使用最舒服的一个库,本文将介绍用HandyJSON来进行Model和JSON间的互相转换。而HandyJSON另辟蹊径,采用Swift反射+内存赋值的方式来构造Model实例,规避了上述两个方案遇到的问题。所以我们要定义一个Mapping函数来做这两个支持:就这样,HandyJSON完美地帮我们进行了JSON到Model类的转换。把Model转换为JSON文本HandyJSON还提供了把Model类序列化为JSON文本的能力,简直无情。

  8. 数组 – 在swift中存储对数组的引用

    我错过了一些允许我这样做的Swift构造吗?你必须使用NSArray或NSMutableArray,因为SwiftArrays是值类型,所以任何赋值都会复制.

  9. android – 如何在Realm for Java中将RealmObject序列化为JSON?

    也就是说,使用RealmObject并将其序列化为JSON?它还应该序列化该对象内的任何RealmList.解决方法来自英国的基督徒在这里.RealmforAndroid目前没有任何此类方法,虽然核心数据库实际上支持JSON序列化,所以现在你要么必须手动操作,要么使用像GSON这样的第三方工具然而).

  10. android – GSON反序列化自定义对象数组

    我正在尝试使用GSON在Android中序列化/反序列化JSON.我有两个类看起来像这样:和:我正在使用GSON来序列化/反序列化数据.我像这样序列化:这将生成如下所示的JSON:我这样反序列化:我打电话的时候收到错误.我不知道这个错误意味着什么.我不认为自己做了任何严重的错误.有帮助吗?解决方法将您的代码更改为:使用Interfaces是一个很好的做法,GSON要求.Gson将javascript中的数组“[]”转换为LinkedList对象.在您的代码中,GSON尝试在_users字段中注入一个Lin

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部