0、前言

本文主要对几种常见Java序列化方式进行实现。包括Java原生以流的方法进行的序列化、Json序列化、FastJson序列化、Protobuff序列化。
1、Java原生序列化
Java原生序列化方法即通过Java原生流(InputStream和OutputStream之间的转化)的方式进行转化。需要注意的是JavaBean实体类必须实现Serializable接口,否则无法序列化。Java原生序列化代码示例如下所示:
运行结果:
java serialize: 8ms; 总大小:420
复制代码 代码如下:
java deserialize: 1ms; User: User [userId=null, userName=张三, passWord=123456, userInfo=张三是一个很牛的人, friends=[User [userId=null, userName=李四, passWord=123456, userInfo=李四是一个很牛的人, friends=null], User [userId=null, userName=王五, passWord=123456, userInfo=王五是一个很牛的人, friends=null]]]
2、Json序列化
Json序列化一般会使用jackson包,通过ObjectMapper类来进行一些操作,比如将对象转化为byte数组或者将json串转化为对象。现在的大多数公司都将json作为服务器端返回的数据格式。比如调用一个服务器接口,通常的请求为xxx.json?a=xxx&b=xxx的形式。Json序列化示例代码如下所示:
package serialize;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
*
* @author liqqc
*
*/
public class JsonSerialize {
public static void main(String[] args) throws IOException {
new JsonSerialize().start();
}
public void start() throws IOException {
User u = new User();
List<User> friends = new ArrayList<>();
u.setUserName("张三");
u.setPassWord("123456");
u.setUserInfo("张三是一个很牛的人");
u.setFriends(friends);
User f1 = new User();
f1.setUserName("李四");
f1.setPassWord("123456");
f1.setUserInfo("李四是一个很牛的人");
User f2 = new User();
f2.setUserName("王五");
f2.setPassWord("123456");
f2.setUserInfo("王五是一个很牛的人");
friends.add(f1);
friends.add(f2);
ObjectMapper mapper = new ObjectMapper();
Long t1 = System.currentTimeMillis();
byte[] writeValueAsBytes = null;
for (int i = 0; i < 10; i++) {
writeValueAsBytes = mapper.writeValueAsBytes(u);
}
System.out.println("json serialize: " + (System.currentTimeMillis() - t1) + "ms; 总大小:" + writeValueAsBytes.length);
Long t2 = System.currentTimeMillis();
User user = mapper.readValue(writeValueAsBytes, User.class);
System.out.println("json deserialize: " + (System.currentTimeMillis() - t2) + "ms; User: " + user);
}
}
运行结果:
json serialize: 55ms; 总大小:341
复制代码 代码如下:
json deserialize: 35ms; User: User [userId=null, userName=张三, passWord=123456, userInfo=张三是一个很牛的人, friends=[User [userId=null, userName=李四, passWord=123456, userInfo=李四是一个很牛的人, friends=null], User [userId=null, userName=王五, passWord=123456, userInfo=王五是一个很牛的人, friends=null]]]
3、FastJson序列化
fastjson 是由阿里巴巴开发的一个性能很好的Java 语言实现的 Json解析器和生成器。特点:速度快,测试表明fastjson具有极快的性能,超越任其他的Java json parser。功能强大,完全支持java bean、集合、Map、日期、Enum,支持范型和自省。无依赖,能够直接运行在Java SE 5.0以上版本
支持Android。使用时候需引入FastJson第三方jar包。FastJson序列化代码示例如下所示:
package serialize;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.JSON;
/**
*
* @author liqqc
*
*/
public class FastJsonSerialize {
public static void main(String[] args) {
new FastJsonSerialize().start();
}
public void start(){
User u = new User();
List<User> friends = new ArrayList<>();
u.setUserName("张三");
u.setPassWord("123456");
u.setUserInfo("张三是一个很牛的人");
u.setFriends(friends);
User f1 = new User();
f1.setUserName("李四");
f1.setPassWord("123456");
f1.setUserInfo("李四是一个很牛的人");
User f2 = new User();
f2.setUserName("王五");
f2.setPassWord("123456");
f2.setUserInfo("王五是一个很牛的人");
friends.add(f1);
friends.add(f2);
//序列化
Long t1 = System.currentTimeMillis();
String text = null;
for(int i = 0; i<10; i++) {
text = JSON.toJSONString(u);
}
System.out.println("fastJson serialize: " +(System.currentTimeMillis() - t1) + "ms; 总大小:" + text.getBytes().length);
//反序列化
Long t2 = System.currentTimeMillis();
User user = JSON.parseObject(text, User.class);
System.out.println("fastJson serialize: " + (System.currentTimeMillis() -t2) + "ms; User: " + user);
}
}
运行结果:
fastJson serialize: 284ms; 总大小:269
复制代码 代码如下:
fastJson serialize: 26ms; User: User [userId=null, userName=张三, passWord=123456, userInfo=张三是一个很牛的人, friends=[User [userId=null, userName=李四, passWord=123456, userInfo=李四是一个很牛的人, friends=null], User [userId=null, userName=王五, passWord=123456, userInfo=王五是一个很牛的人, friends=null]]]
4、ProtoBuff序列化
ProtocolBuffer是一种轻便高效的结构化数据存储格式,可以用于结构化数据序列化。适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。
优点:跨语言;序列化后数据占用空间比JSON小,JSON有一定的格式,在数据量上还有可以压缩的空间。
缺点:它以二进制的方式存储,无法直接读取编辑,除非你有 .proto 定义,否则无法直接读出 Protobuffer的任何内容。
其与thrift的对比:两者语法类似,都支持版本向后兼容和向前兼容,thrift侧重点是构建跨语言的可伸缩的服务,支持的语言多,同时提供了全套RPC解决方案,可以很方便的直接构建服务,不需要做太多其他的工作。 Protobuffer主要是一种序列化机制,在数据序列化上进行性能比较,Protobuffer相对较好。
ProtoBuff序列化对象可以很大程度上将其压缩,可以大大减少数据传输大小,提高系统性能。对于大量数据的缓存,也可以提高缓存中数据存储量。原始的ProtoBuff需要自己写.proto文件,通过编译器将其转换为java文件,显得比较繁琐。百度研发的jprotobuf框架将Google原始的protobuf进行了封装,对其进行简化,仅提供序列化和反序列化方法。其实用上也比较简洁,通过对JavaBean中的字段进行注解就行,不需要撰写.proto文件和实用编译器将其生成.java文件,百度的jprotobuf都替我们做了这些事情了。
一个带有jprotobuf注解的JavaBean如下所示,如果你想深入学习可以参照https://github.com/google/protobuf。
package serialize;
import java.io.Serializable;
import java.util.List;
import com.baidu.bjf.remoting.protobuf.FieldType;
import com.baidu.bjf.remoting.protobuf.annotation.Protobuf;
public class User implements Serializable {
private static final long serialVersionUID = -7890663945232864573L;
@Protobuf(fieldType = FieldType.INT32, required = false, order = 1)
private Integer userId;
@Protobuf(fieldType = FieldType.STRING, required = false, order = 2)
private String userName;
@Protobuf(fieldType = FieldType.STRING, required = false, order = 3)
private String passWord;
@Protobuf(fieldType = FieldType.STRING, required = false, order = 4)
private String userInfo;
@Protobuf(fieldType = FieldType.OBJECT, required = false, order = 5)
private List<User> friends;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public String getUserInfo() {
return userInfo;
}
public void setUserInfo(String userInfo) {
this.userInfo = userInfo;
}
public List<User> getFriends() {
return friends;
}
public void setFriends(List<User> friends) {
this.friends = friends;
}
@Override
public String toString() {
return "User [userId=" + userId + ", userName=" + userName + ", passWord=" + passWord + ", userInfo=" + userInfo
+ ", friends=" + friends + "]";
}
}
jprotobuf序列化代码示例如下所示:
package serialize;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.baidu.bjf.remoting.protobuf.Codec;
import com.baidu.bjf.remoting.protobuf.ProtobufProxy;
/**
*
* @author liqqc
*
*/
public class ProtoBuffSerialize {
public static void main(String[] args) throws IOException {
new ProtoBuffSerialize().start();
}
public void start() throws IOException {
Codec<User> studentClassCodec = ProtobufProxy.create(User.class, false);
User u2 = new User();
List<User> friends = new ArrayList<>();
u2.setUserName("张三");
u2.setPassWord("123456");
u2.setUserInfo("张三是一个很牛的人");
u2.setFriends(friends);
User f1 = new User();
f1.setUserName("李四");
f1.setPassWord("123456");
f1.setUserInfo("李四是一个很牛的人");
User f2 = new User();
f2.setUserName("王五");
f2.setPassWord("123456");
f2.setUserInfo("王五是一个很牛的人");
friends.add(f1);
friends.add(f2);
Long stime_jpb_encode = System.currentTimeMillis();
byte[] bytes = null;
for(int i = 0; i<10; i++) {
bytes = studentClassCodec.encode(u2);
}
System.out.println("jprotobuf序列化耗时:" + (System.currentTimeMillis() - stime_jpb_encode) + "ms; 总大小:" + bytes.length);
Long stime_jpb_decode = System.currentTimeMillis();
User user = studentClassCodec.decode(bytes);
Long etime_jpb_decode = System.currentTimeMillis();
System.out.println("jprotobuf反序列化耗时:"+ (etime_jpb_decode-stime_jpb_decode) + "ms; User: " + user);
}
}
运行结果:
jprotobuf序列化耗时:9ms; 总大小:148
复制代码 代码如下:
jprotobuf反序列化耗时:0ms; User: User [userId=null, userName=张三, passWord=123456, userInfo=张三是一个很牛的人, friends=[User [userId=null, userName=李四, passWord=123456, userInfo=李四是一个很牛的人, friends=null], User [userId=null, userName=王五, passWord=123456, userInfo=王五是一个很牛的人, friends=null]]]
5、总结
我们通过Main方法来进行对比测试,(但是通过测试发现少量数据无法准确显示每种序列化方式的优劣,故这里无法给出比较好的答案,仅供参考)。示例代码如下所示:
package serialize;
import java.io.IOException;
/**
* @author liqqc
*/
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ProtoBuffSerialize protoBuffSerialize = new ProtoBuffSerialize();
protoBuffSerialize.start();
System.err.println();
System.err.println();
JavaSerialize javaSerialize = new JavaSerialize();
javaSerialize.start();
System.err.println();
JsonSerialize jsonSerialize = new JsonSerialize();
jsonSerialize.start();
System.err.println();
FastJsonSerialize fastJsonSerialize = new FastJsonSerialize();
fastJsonSerialize.start();
}
}
运行结果:
jprotobuf序列化耗时:7ms; 总大小:148
jprotobuf反序列化耗时:0ms
java serialize: 6ms; 总大小:420
java deserialize: 1ms
json serialize: 37ms; 总大小:341
json deserialize: 27ms
fastJson serialize: 173ms; 总大小:269
fastJson serialize: 35ms
上面的测试仅供参考,并不能代表通过大量数据进行测试的结果。可以发现:序列化后对象的所占大小上:protobuff序列化所占总大小是最少的;其次是fastJson序列化;最后是json序列化和java原生序列化。对于序列化耗时,上面的测试不准。
还是去看看专业测试分析吧,具体情况可以进去看看https://github.com/eishay/jvm-serializers/wiki
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# java实现序列化
# java实现序列化的方法
# javabean实现序列化
# java中transient关键字用法分析
# 说一说java关键字final和transient
# Java中的transient关键字介绍
# Java transient关键字使用小记
# Java transient 关键字详解及实例代码
# java 序列化对象 serializable 读写数据的实例
# 深入理解Java对象的序列化与反序列化的应用
# Java中对象序列化与反序列化详解
# Java实现序列化与反序列化的简单示例
# java对象序列化与反序列化的默认格式和json格式使用示例
# Java transient关键字与序列化操作实例详解
# 的人
# 是一个
# 序列化
# 李四
# 王五
# 所示
# 张三
# 将其
# 是一种
# 数据存储
# 转化为
# 结构化
# 的是
# 仅供参考
# 数据格式
# 很好
# 太多
# 不需要
# 是由
# 阿里巴巴
相关文章:
单页制作网站有哪些,朋友给我发了一个单页网站,我应该怎么修改才能把他变成自己的呢,请求高手指点迷津?
建站之星后台搭建步骤解析:模板选择与产品管理实操指南
网站制作费用多少钱,一个网站的运营,需要哪些费用?
上海网站制作网站建设公司,建筑电工证网上查询系统入口?
佛山网站制作系统,佛山企业变更地址网上办理步骤?
招商网站制作流程,网站招商广告语?
广州美橙建站如何快速搭建多端合一网站?
,有什么在线背英语单词效率比较高的网站?
成都响应式网站开发,dw怎么把手机适应页面变成网页?
如何在云主机上快速搭建网站?
网站制作的软件有哪些,制作微信公众号除了秀米还有哪些比较好用的平台?
建站主机服务器选型指南与性能优化方案解析
,sp开头的版面叫什么?
如何用虚拟主机快速搭建网站?详细步骤解析
Swift中switch语句区间和元组模式匹配
如何通过西部数码建站助手快速创建专业网站?
如何快速辨别茅台真假?关键步骤解析
如何在自有机房高效搭建专业网站?
深圳网站制作平台,深圳市做网站好的公司有哪些?
微信小程序 五星评分(包括半颗星评分)实例代码
如何选择网络建站服务器?高效建站必看指南
建站之星安装后如何自定义网站颜色与字体?
企业网站制作公司网页,推荐几家专业的天津网站制作公司?
无锡营销型网站制作公司,无锡网选车牌流程?
枣阳网站制作,阳新火车站打的到仙岛湖多少钱?
清除minerd进程的简单方法
陕西网站制作公司有哪些,陕西凌云电器有限公司官网?
建站OpenVZ教程与优化策略:配置指南与性能提升
在线教育网站制作平台,山西立德教育官网?
如何在新浪SAE免费搭建个人博客?
如何快速搭建高效服务器建站系统?
香港服务器如何优化才能显著提升网站加载速度?
电商网站制作公司有哪些,1688网是什么意思?
简历在线制作网站免费,免费下载个人简历的网站是哪些?
专业的网站制作设计是什么,如何制作一个企业网站,建设网站的基本步骤有哪些?
Dapper的Execute方法的返回值是什么意思 Dapper Execute返回值详解
,交易猫的商品怎么发布到网站上去?
建站主机助手选型指南:2025年热门推荐与高效部署技巧
网站设计制作企业有哪些,抖音官网主页怎么设置?
,想在网上投简历,哪几个网站比较好?
香港服务器WordPress建站指南:SEO优化与高效部署策略
网站制作和推广的区别,想自己建立一个网站做推广,有什么快捷方法马上做好一个网站?
如何快速搭建高效可靠的建站解决方案?
智能起名网站制作软件有哪些,制作logo的软件?
江苏网站制作公司有哪些,江苏书法考级官方网站?
建站之星安装模板失败:服务器环境不兼容?
建站之星后台密码遗忘或太弱?如何重置与强化?
高端企业智能建站程序:SEO优化与响应式模板定制开发
如何通过万网虚拟主机快速搭建网站?
如何快速建站并高效导出源代码?
*请认真填写需求信息,我们会在24小时内与您取得联系。