Java的序列化

news2024/11/25 11:58:57

写在前面

本文看下序列化和反序列化相关的内容。

源码 。

1:为什么,什么是序列化和反序列化

Java对象是在jvm的堆中的,而堆其实就是一块内存,如果jvm重启数据将会丢失,当我们希望jvm重启也不要丢失某些对象,或者是需要将某些对象传递到其他服务器(rpc有没有!!!)时就需要使用到序列化和反序列化,因为序列化就是将Java对象转换为文件,而反序列化就是加载文件并生成对象在堆中。
在这里插入图片描述

2:Java的序列化和反序列化

Java想要序列化和反序列化,必须实现java.io.Serializable接口,并给变量serialVersionUID赋值,该值用来标识Java类文件的版本。如下序列化和反序列化的例子:

@SneakyThrows
private static void javaDeserialize() {
    ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("d:\\test\\xxx.obj"));
    Student student = (Student) objectInputStream.readObject();
    System.out.println("java反序列化student完成");
    System.out.println(student);
}

@SneakyThrows
private static void javaSerialize() throws IOException {
    Student student = new Student();
    student.setName("张三");
    student.setAge(99);
    ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("d:\\test\\xxx.obj"));
    // 如果没有实现java.io.Serializable接口将会抛出异常java.io.NotSerializableException
    objectOutputStream.writeObject(student);
    objectOutputStream.close();
    System.out.println("java序列化student完成");
}

java序列化的问题:

1:无法跨平台
    如Java对象序列化的结果反序列化为python的对象,这样就限制了其不适合某些使用场景,如rpc的场景中就无法使用这种序列化方式,因为rpc需要支持异构的系统
2:序列化的文件大
    这样占用磁盘大,网络传输速度慢,占用带宽,反序列化的速度也慢,这样就限制了其不适合某些使用场景,如rpc,rpc需要尽量快的序列化和反序列化速度,以提高性能
3:序列化的速度慢
    还是因为其序列化结果的内容多

以上的问题我们可以使用专门的序列化框架来解决,如hessian。

3:hessian的序列化和反序列化

dubbo 默认使用的是该序列化方式,将来可能会优化成性能更优的序列化方式如kryo,fst等。

hessian支持语言无关的序列化和反序列化,并且速度更快,序列化的结果更小,如下:

private void hessianSerialize() {
    Student stu = new Student("hessian",1);
    byte[] obj = serialize(stu);
    System.out.println("hessian serialize result length = "+obj.length);
    byte[] obj2 = serialize2(stu);
    System.out.println("hessian2 serialize result length = "+obj2.length);
    byte[] other = jdkSerialize(stu);
    System.out.println("jdk serialize result length = "+other.length);
    Student student = deserialize2(obj2);
    System.out.println("deserialize result entity is "+student);
}

具体看文章头源码。
运行结果如下:

hessian serialize result length = 65
hessian2 serialize result length = 59
jdk serialize result length = 101
deserialize result entity is Student(name=hessian, age=1)

可以看到结果的大小jdk序列化<hessian序列化<hessian2序列化,所以如果工作中有这种需求,建议使用hessian2。

4:arvo的序列化和反序列化

使用步骤如下:

1:定义.avsc描述文件
2:通过avro-tool.jar,以.avsc描述文件作为输入生成pojo
3:通过avro.jar的API进行序列化(生成.avro文件)和反序列化

首先我们需要定义IDL,命名为User.avsc:

{
    "namespace": "dongshi.daddy.seriablize.avro",
    "type": "record",
    "name": "User",
    "fields": [
        {"name": "name", "type": "string"},
        {"name": "id", "type": "int"},
        {"name": "salary", "type": "int"},
        {"name": "age", "type": "int"},
        {"name": "address", "type": "string"}
    ]
}

接着通过avro-tools.jar生成pojo,如下:

$ java -jar avro-tools-1.8.2.jar compile schema User.avsc res
Input files to compile:
  User.avsc
log4j:WARN No appenders could be found for logger (AvroVelocityLogChute).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

然后我们将生成的User.java文件拷贝到classpath的dongshi.daddy.seriablize.avro目录,接着就可以执行序列化和反序列化了,首先执行序列化:

@Test
public void testAvroSerialize() throws Exception {
// 声明并初始化User对象
    // 方式一
    User user1 = new User();
    user1.setName("wqbin");
    user1.setId(1);
    user1.setSalary(1000);
    user1.setAge(20);
    user1.setAddress("beijing");

    // 方式二 使用构造函数
// Alternate constructor
    User user2 = new User("wang", 2, 1000, 19, "guangzhou");

// 方式三,使用Build方式
// Construct via builder
    User user3 = User.newBuilder()
            .setName("bin")
            .setId(3)
            .setAge(21)
            .setSalary(2000)
            .setAddress("shenzhen")
            .build();
    String userDir = System.getProperty("user.dir");
    System.out.println("userDir is: " + userDir);
    String path = userDir + "/User.avro"; // avro文件存放目录
    DatumWriter<User> userDatumWriter = new SpecificDatumWriter<User>(User.class);
    DataFileWriter<User> dataFileWriter = new DataFileWriter<User>(userDatumWriter);
    dataFileWriter.create(user1.getSchema(), new File(path));
// 把生成的user对象写入到avro文件
    dataFileWriter.append(user1);
    dataFileWriter.append(user2);
    dataFileWriter.append(user3);
    dataFileWriter.close();
}

生成文件如下:
在这里插入图片描述

接着执行反序列化:

@Test
public void testAvroDeserialize() throws Exception {
    DatumReader<User> reader = new SpecificDatumReader<User>(User.class);
    DataFileReader<User> dataFileReader = new DataFileReader<User>(new File(System.getProperty("user.dir") + "/User.avro"), reader);
    User user = null;
    while (dataFileReader.hasNext()) {
        user = dataFileReader.next();
        System.out.println(user);
    }
}

输出如下内容则为成功:

{"name": "wqbin", "id": 1, "salary": 1000, "age": 20, "address": "beijing"}
{"name": "wang", "id": 2, "salary": 1000, "age": 19, "address": "guangzhou"}
{"name": "bin", "id": 3, "salary": 2000, "age": 21, "address": "shenzhen"}

Process finished with exit code 0

5:kryo的序列化和反序列化

kryo是底层使用了ASM字节码技术,所以其只能使用在基于JVM的语言上,如Java,scala,kotlin等,接下来看下其如何使用。

  • 首先引入pom:
<dependency>
    <groupId>com.esotericsoftware</groupId>
    <artifactId>kryo</artifactId>
    <version>5.2.0</version>
</dependency>
  • 序列化:
@Test
public void testKrypSerialize() throws Exception {
    Kryo kryo = new Kryo();
    kryo.register(SomeClass.class);

    SomeClass someClass = new SomeClass();
    someClass.value = "dongshidaddy";
    Output output = new Output(new FileOutputStream(userDir + "/someCls.bin"));
    kryo.writeObject(output, someClass);
    output.close();
}

运行后:
在这里插入图片描述

  • 反序列化
@Test
public void testKrypDeserialize() throws Exception {
    Kryo kryo = new Kryo();
    kryo.register(SomeClass.class);

    Input input = new Input(new FileInputStream(userDir + "/someCls.bin"));
    SomeClass someClassFromBin = kryo.readObject(input, SomeClass.class);
    System.out.println(someClassFromBin.value);
}

运行后:

dongshidaddy

Process finished with exit code 0

6:fst的序列化和反序列化

java的序列化和反序列化方式,性能优秀(jdk原生序列化速度的10倍,序列化结果体积1/3左右),如果有序列化的需求可以考虑使用。看下如何使用。

  • 引入pom
<dependency>
    <groupId>de.ruedigermoeller</groupId>
    <artifactId>fst</artifactId>
    <version>2.04</version>
</dependency>
  • 序列化和反序列化
// fst序列化和反序列化
@Test
public void testFstSerializeAndDescrialize() {
    dongshi.daddy.seriablize.fst.User bean = new dongshi.daddy.seriablize.fst.User();
    bean.setUsername("xxxxx");
    bean.setPassword("123456");
    bean.setAge(1000000);
    byte[] byteBean = configuration.asByteArray(bean);
    System.out.println("序列化的字节大小是:" + byteBean.length);
    // 反序列化
    dongshi.daddy.seriablize.fst.User resultBean = (dongshi.daddy.seriablize.fst.User) configuration.asObject(byteBean);
    System.out.println("fst反序列化的结果是:" + resultBean);
}

输出如下内容则为成功:

序列化的字节大小是:68
fst反序列化的结果是:User(username=xxxxx, age=1000000, password=123456)

Process finished with exit code 0

写在后面

巨人的肩膀

再来认识一下 Java 序列化 。

Hessian序列化实例 。

Avro从入门到入土 。

深入浅出序列化(2)——Kryo序列化 。

Kryo 和 FST 序列化 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1022547.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux学习-Redis主从和哨兵

主从复制 一主一从结构 # 配置host61为主服务器 [roothost61 ~]# yum -y install redis [roothost61 ~]# vim /etc/redis.conf bind 192.168.88.61 #设置服务使用的Ip地址 port 6379 #设置服务使用的端口号 使用默认端口即可 [roothost61 ~]# systemctl start redis [rooth…

深入探索图像处理:从基础到高级应用

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 图像处理是计算机视觉领…

高数(上) 第一章:函数、极限、连续

文章目录 一、函数1.函数的概念、基本初等函数2.函数的性质 /函数四性态1.单调性2.奇偶性(3)导函数的奇偶性 3.周期性4.有界性5.对称性 3.基本不等式4.开根要带绝对值 二、极限1.极限的概念①数列极限②函数极限需要区分左右极限的三种问题 &#xff08;左右极限有区别&#xf…

[网鼎杯 2020 朱雀组]Nmap 通过nmap写入木马 argcmd过滤实现逃逸

这道题也很好玩 啊 原本以为是ssrf 或者会不会是rce 结果是通过nmap写入木马 我们来玩一下 传入木马 映入眼帘是nmap 我们首先就要了解nmap的指令 Nmap 相关参数-iL 读取文件内容&#xff0c;以文件内容作为搜索目标 -o 输出到文件-oN 标准保存-oX XML保存-oG Grep保存-oA…

Python所有方向的学习路线,你们要的知识体系在这,千万别做了无用功!

一直以来都有很多想学习Python的朋友们问我&#xff0c;学Python怎么学&#xff1f;爬虫和数据分析怎么学&#xff1f;web开发的学习路线能教教我吗&#xff1f; 我先告诉大家一个点&#xff0c;不管你是报了什么培训班&#xff0c;还是自己在通过各种渠道自学&#xff0c;你一…

测试团队的建设和管理

一.测试团队的建设 软件的质量不是靠测试出来的&#xff0c;而是靠产品开发团队&#xff08;需求分析工程师&#xff0c;系统设计工程师&#xff0c;程序员&#xff0c;测试工程师&#xff0c;技术支持工程师等&#xff09;所有成员的共同努力来获得的。 软件测试团队不仅仅是指…

计算机毕业设计 基于SSM+Vue的校园短期闲置资源置换平台的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

静态手势识别和动态手势识别的区别和技术路线简介

人类能够轻松识别身体和手语。这是可能的&#xff0c;因为视觉和突触相互作用是在大脑发育过程中形成的。为了在计算机中复制这种技能&#xff0c;需要解决一些问题&#xff1a;如何分离图像中感兴趣的对象以及哪种图像捕获技术和分类技术更合适等等。 计算的发展和新技术的易用…

2023年黑客零基础从入门到精通学习成长路线(超多图、非常详细),看完这一篇就够了。

怎样规划学习路线&#xff1f; 如果你是一个安全行业新人&#xff0c;我建议你先从网络安全或者Web安全/渗透测试这两个方向先学起&#xff0c;一是市场需求量高&#xff0c;二则是发展相对成熟入门比较容易。 值得一提的是&#xff0c;学网络安全&#xff0c;是先网络后安全…

【腾讯云 Cloud Studio 实战训练营】- 云IDE Cloud Studio如何在项目中增效的实践之路

一、 引言&#xff1a; 代码开发随着云计算技术的不断发展&#xff0c;无服务器计算应运而生。 无服务器计算由云平台统一管理后端服务及资源&#xff0c;避免了开发过程中繁琐的集群搭建及系统运维工作。在提高整体资源利用率的同时&#xff0c;借助云 IDE 还能够帮助开发者…

SpringBoot分页实现查询数据

1.原生查询 1.1创建分页查询实体类 package com.itheima.pojo;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.util.List;//分页查询结果封装类 Data NoArgsConstructor AllArgsConstructor public class PageBean {pr…

华为项目管理的43210法则

【微|信|公|众|号&#xff1a;厦门微思网络】

Pytorch实现的LSTM、RNN模型结构

一、LSTM模型 import torch from torch import nn import torchvision.datasets as dsets import torchvision.transforms as transforms import matplotlib.pyplot as plttorch.manual_seed(1)# Hyper Parameters EPOCH 1 # 训练整批数据多少次, 为了节约时间, 我们…

PCA9306——I2C电平转换模块

PCA930——I2C电平转换 PCA9306是双向I2C总线和SMBus电压电平转换器&#xff0c;具有启用&#xff08;EN&#xff09;输入&#xff0c;可从1.0 V到3.6 V和1.8 V到5.5V的电平转换。 PCA9306允许在1.0 V和5V之间的双向电压转换&#xff0c;而不使用方向引脚。开关的低接通状态电…

自监督学习模型发展综述:Inst Disc、Inva Sread、MOCO、SimCLR、BYOL

文章目录 一、Inst Disc研究意义价值个体判别&#xff08;instance discrimination&#xff09;特点实现方法如何训练CNN大量负样本如何存储前向传播过程Proximal Regularization超参数设置 二、Inva Sread特点原理如何选取正负样本前向传播过程目标函数模型效果不够好的原因 M…

JDK jps命令复习

之前写过jdk命令工具的博文&#xff0c;下面复习jps命令&#xff1b; jps 是 Java Process Status Tool 的简称,它的作用是为了列出所有正在运行中的 Java 虚拟机进程和相关信息&#xff1b; jps 命令参数 -q 只输出进程 ID,省略主类的名称 -m 输出虚拟机进程启动时传递…

【PyTorch攻略(2/7)】 加载数据集

一、说明 PyTorch提供了两个数据原语&#xff1a;torch.utils.data.DataLoader和torch.utils.data.Dataset&#xff0c;允许您使用预加载的数据集以及您自己的数据。数据集存储样本及其相应的标签&#xff0c;DataLoader 围绕数据集包装一个可迭代对象&#xff0c;以便轻松访问…

大模型助力企业数据驱动,火山引擎数智平台发布AI助手

9月19日&#xff0c;火山引擎在其举办的“V-Tech数据驱动科技峰会”上宣布&#xff0c;火山引擎数智平台VeDI推出“AI助手”&#xff0c;通过接入人工智能大模型&#xff0c;帮助企业提升数据处理和查询分析的效率。即使是不会写代码的运营人员&#xff0c;和大模型对话也能做好…

Vue3封装知识点(三)依赖注入:project和inject详细介绍

Vue3封装知识点&#xff08;三&#xff09;依赖注入&#xff1a;project和inject详细介绍 文章目录 Vue3封装知识点&#xff08;三&#xff09;依赖注入&#xff1a;project和inject详细介绍一、project和inject是什么二、为了解决什么问题三、project和inject如何使用1.provid…

四川百幕晟科技:抖店精选联盟怎么使用?

近年来&#xff0c;电商平台的兴起让很多人纷纷加入进来&#xff0c;希望通过在网上销售产品来赚取更多的利润。在这个竞争激烈的市场中&#xff0c;如何找到稳定的渠道来推广自己的产品成为了每个卖家的追求。抖店精选联盟是一个不错的选择&#xff0c;可以帮助卖家快速提升销…