内容简介:Java 常用序列化解析
java常用序列化解析
认识序列化
序列化 对于每一个 程序员 都算是再熟悉不过的名词了,但是对于市面是各种流行的序列化方式又是否真正了解并能找出一个最适合的序列化方式呢!
概念
序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
理解
按上述描述的话 简单的理解就是某一天你对象惹你生气了,怎么办!忍,是不可能了,那就把他给序列化一下 1.选个规则 比如编个号 2.拿起指甲刀 按照编号大卸八十八块。但是当你气消了 怎么办? 一堆脂肪可不会说话,反序列化不就行了 真傻,幸好之前有编号 按照编号再组装到一起 完活。 简单吧 有对象的小朋友可以尝试下!
引玉
估计大家也都清楚了什么是序列化和反序列化接下来就给大家浅析下 java 常用的几种序列化方式: JDK自带序列化、JSON序列化、Protostuff序列化 的使用以及实现原理。
JDK序列化
创建要序列化的实体
正反序列化实现
此时会发现JDK自带的序列化在使用上很简单直接通过 ObjectOutputStream 的 writeObject() 方法将 person 对象写入到了一个byte数组里 而反序列化的时候再通过 ObjectInputStream() 的 readObject() 转成对象 并且强转成 Person 的对象 那么就引申出一个猜想: 是不是在序列化时将对象的所有内容信息都进行了存储!
验证猜想之前先给大家看下结果吧!
接着小编一顿源码分析 找到这段代码
结论
JDK自带的序列化方式稳定性很高因为他将所有的内容都涵盖在序列化后的数组对象里但是因此也会导致一个问题 就是占用了过多的空间去存储并不需要的那些东西,这也是我们对JDK序列化避而远之的原因之一。那Json序列化又会有什么优化吗
JSON序列化
用例
结果
结果证明json序列化的结果不到jdk序列化的一半,说到这儿聪明的小伙伴都已经为什么了 是的看下这张图你就知道了
就是因为json格式的数据只保留了key-value 而其他的无关属性都没保存,所以在反序列化的时候需要使用类来做一个反转的依据,这里就不过多的做说明了!
protostuff 序列化
protostuff是基于protobuff的一种序列化方式,相较于protobuf它更简单不需要再手动创建.proto文件等过程! 使用protostuff首先我们需要引入相关的依赖
<dependency> <groupId>io.protostuff</groupId> <artifactId>protostuff-runtime</artifactId> <version>1.5.3</version> </dependency> <dependency> <groupId>io.protostuff</groupId> <artifactId>protostuff-core</artifactId> <version>1.5.3</version> </dependency>
DEMO
下面我们来分析下protostuff的序列化过程
首先引入一个 schema 的概念
官方的解释是 schema是: 对象的序列化逻辑 一个对象的反序列化逻辑 对对象所需字段的验证 对象的字段名到字段号的映射 对象的实例化。
个人的理解: 基于类本身所提炼出来的正反序列化所需的所有关键信息!用于正反序列化的验证及实例化
实现过程
在序列化的时候会根据类型的不同调用RuntimeUnsafeFieldFactory类下相应匿名类的writeto()方法进行序列化,序列化的时候首先会 在类 ProtostuffOutput 下makeTag
我们可以看出这个Tag包含了 fieldNumber 和 WIRETYPE_VARINT 前面的fieldNum代表的是成员变量的序号 后面的WIRETYPE代表的是序列化类型由此我们大概可以了解到protostuff的一些玄机 json用的是变量名 而protostuff用的是变量序号以及类型做标识!
猜想
1.protostuff序列化和变量的名字无关!
2.从后面增加减少变量不影响反序列化!
3.当序列化的变量属性变化了是不是序列化失败!
这时我们翻出之前DEMO的运行结果
通过结果我们可以看出Dog的实体能正常反序列化出Person的实体而Cat的实体却报出异常,同时Dog增加的变量为null,所以上面的猜想是成立的,同时发现序列化以后的byte数组是最小的也符合预期
最后声明 本文只是从宏观方面对各种序列化进行分析介绍,并未深入到各序列化底层对不同数据类型的值转成byte[]的具体实现 在底层方面protostuff也是有所优化的有了这些了解相信大家一定会更好的评估自己的需求选择适合自己的序列化方式。
部门招聘
高级Java开发工程师
工作职责:
1、负责58同城APP,58同镇等相关后端研发工作;
2、负责基础平台的架构设计,核心代码开发;
3、调研并掌握业内通用技术方案,引入项目迭代,提升研发效率;
职位要求:
1、3年以上Java互联网项目开发经验;
2、Java基础扎实,编码规范,程序具备较高的健壮性,熟悉常用设计模式;
3、对MVC框架、RPC框架、基础服务组件等有深入的研究;
4、掌握 Linux 环境下的网络编程、多线程编程,数据结构和算法能力良好;
5、对高并发高可用系统设计有深入的实践经验;
6、具有高度的责任心、勇于承担责任,能承受较强的工作压力;
7、积极主动,敢于接受挑战,有较强的团队合作精神;
高级前端研发工程师
工作职责:
1、负责58同城App前端产品研发;
2、负责58同城前端无线产品某一技术方向,人才培养;
3、前端研发所需类库、框架、脚手架搭建;
4、交互模式调研及创新(React,ReactNative);
职位要求:
1、计算机及相关专业本科以上学历;
2、3年以上前端开发经验,负责过复杂应用的前端设计和开发 ;
3、精通web前端技术(js/css/html),熟悉主流框架类库的设计实现、w3c标准,熟悉ES6/7优先;
4、熟悉前端模块化开发方式(commonjs/webpack …);
5、熟悉移动端开发、自适应布局和开发调试工具,熟悉hybrid app开发;
6、掌握一门后端语言(node/java/php...),对前后端合作模式有深入理解;
7、有良好的产品意识和团队合作意识,能够和产品、UI交互部门协作完成产品面向用户端的呈现;
8、有技术理想,致力于用技术去推动和改变前端研发;
9、熟悉Vue/React/ReactNative优先,有BAT等公司经验优先;
高级Android开发工程师
岗位描述:
1、负责58同城App的研发工作;
2、肩负平台化任务(插件框架,Walle,Hybrid,WubaRN) ;
3、维护和开发服务库,公共库的工作;
4、调研Android前端技术;
5、提升开发效率和应用性能;
职位要求:
1、2年以上的Android开发工作经验;
2、精通Java语言,精通Android Studio开发,了解Gradle编译;
3、精通常用算法、数据结构和架构设计;
4、了解Android性能限制及优化方案;
5、了解常用的开源工具:Volley,RxJava,Fresco等等;
6、了解git, maven等等工具;
7、有插件开发经验,Hybrid开发经验,ReactNative开发经验优先;
8、积极主动、喜欢挑战,有强烈的创业精神,能承受高强度的工作压力;
以上如有小伙伴感兴趣,请发送简历到:
liunz@58ganji.com
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
x86/x64体系探索及编程
邓志 / 电子工业出版社 / 2012-10-1 / 119.00元
本书是对Intel手册所述处理器架构的探索和论证。全书共五大部分,从多个方面对处理器架构相关的知识进行了梳理介绍。书中每个章节都有相应的测试实验,所运行的实验例子都可以在真实的机器上执行。 通过阅读本书,读者应能培养自己动手实验的能力。如果再有一些OS方面的相关知识,基本上就可以写出自己简易的OS核心。 本书适合有一定的x86基础知识,且对了解处理器架构及编程感兴趣的读者阅读。一起来看看 《x86/x64体系探索及编程》 这本书的介绍吧!