全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Java实现几种序列化方式总结

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关键字与序列化操作实例详解  # 的人  # 是一个  # 序列化  # 李四  # 王五  # 所示  # 张三  # 将其  # 是一种  # 数据存储  # 转化为  # 结构化  # 的是  # 仅供参考  # 数据格式  # 很好  # 太多  # 不需要  # 是由  # 阿里巴巴 


相关文章: 上海网站制作网站建设公司,建筑电工证网上查询系统入口?  魔毅自助建站系统:模板定制与SEO优化一键生成指南  宝塔面板创建网站无法访问?如何快速排查修复?  深圳企业网站制作设计,在深圳如何网上全流程注册公司?  网站制作专业公司有哪些,如何制作一个企业网站,建设网站的基本步骤有哪些?  javascript基本数据类型及类型检测常用方法小结  ,交易猫的商品怎么发布到网站上去?  高性能网站服务器配置指南:安全稳定与高效建站核心方案  利用JavaScript实现拖拽改变元素大小  网站专业制作公司,网站编辑是做什么的?好做吗?工作前景如何?  如何用低价快速搭建高质量网站?  学校建站服务器如何选型才能满足性能需求?  如何通过西部数码建站助手快速创建专业网站?  php能控制zigbee模块吗_php通过串口与cc2530 zigbee通信【介绍】  平台云上自助建站如何快速打造专业网站?  建站之星安装模板失败:服务器环境不兼容?  如何配置WinSCP新建站点的密钥验证步骤?  岳西云建站教程与模板下载_一站式快速建站系统操作指南  如何用PHP快速搭建高效网站?分步指南  香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化  建站之星后台密码遗忘?如何快速找回?  建站中国官网:模板定制+SEO优化+建站流程一站式指南  如何通过VPS建站无需域名直接访问?  道歉网站制作流程,世纪佳缘致歉小吴事件,相亲网站身份信息伪造该如何稽查?  网站制作难吗安全吗,做一个网站需要多久时间?  贸易公司网站制作流程,出口贸易网站设计怎么做?  ,网站推广常用方法?  佛山网站制作系统,佛山企业变更地址网上办理步骤?  制作网站哪家好,cc、.co、.cm哪个域名更适合做网站?  开心动漫网站制作软件下载,十分开心动画为何停播?  如何在景安云服务器上绑定域名并配置虚拟主机?  建站之星如何开启自定义404页面避免用户流失?  如何在Mac上搭建Golang开发环境_使用Homebrew安装和管理Go版本  个人网站制作流程图片大全,个人网站如何注销?  购物网站制作公司有哪些,哪个购物网站比较好?  网站专业制作公司有哪些,做一个公司网站要多少钱?  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  网站设计制作企业有哪些,抖音官网主页怎么设置?  如何在IIS中配置站点IP、端口及主机头?  c++怎么编写动态链接库dll_c++ __declspec(dllexport)导出与调用【方法】  Python lxml的etree和ElementTree有什么区别  如何在Windows服务器上快速搭建网站?  如何在局域网内绑定自建网站域名?  专业的网站制作设计是什么,如何制作一个企业网站,建设网站的基本步骤有哪些?  网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?  定制建站方案优化指南:企业官网开发与建站费用解析  电脑免费海报制作网站推荐,招聘海报哪个网站多?  网站app免费制作软件,能免费看各大网站视频的手机app?  免费公司网站制作软件,如何申请免费主页空间做自己的网站?  建站之星后台搭建步骤解析:模板选择与产品管理实操指南 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。