重视网站商务通/公司网站的推广
Java 序列化是一种将对象转换为字节流的过程,可以将对象的状态保存到磁盘文件或通过网络传输。反序列化则是将字节流重新转换为对象的过程。Java 提供了一个强大的序列化框架,允许你在对象的持久化和网络通信中使用它。
一、Java 序列化的基本原理
Java 序列化的基本原理是将一个 Java 对象转换为一个字节序列,以便将其保存到磁盘上的文件或通过网络发送到其他地方。这个字节序列可以随后被反序列化为原始对象。
Java 序列化的主要实现是通过 java.io.Serializable
接口来实现的。只有实现了这个接口的类才能被序列化。该接口没有任何方法,它只是一个标识接口,用来表示一个类的实例可以被序列化。
要序列化一个对象,你可以使用 ObjectOutputStream
类,将对象写入输出流。要反序列化一个对象,可以使用 ObjectInputStream
类,从输入流中读取字节并重新构建对象。
以下是一个简单的 Java 序列化和反序列化的示例:
import java.io.*;class Student implements Serializable {private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}public String toString() {return "Name: " + name + ", Age: " + age;}
}public class SerializationExample {public static void main(String[] args) {// 创建一个 Student 对象Student student = new Student("Alice", 25);// 序列化对象到文件try (FileOutputStream fileOut = new FileOutputStream("student.ser");ObjectOutputStream out = new ObjectOutputStream(fileOut)) {out.writeObject(student);System.out.println("Object has been serialized");} catch (IOException e) {e.printStackTrace();}// 反序列化对象try (FileInputStream fileIn = new FileInputStream("student.ser");ObjectInputStream in = new ObjectInputStream(fileIn)) {Student deserializedStudent = (Student) in.readObject();System.out.println("Object has been deserialized");System.out.println(deserializedStudent);} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}}
}
在这个示例中,我们首先创建一个 Student
类,并实现了 Serializable
接口。然后,我们创建一个 Student
对象,将其序列化到名为 "student.ser" 的文件中,并通过反序列化重新构建对象。
二、序列化版本UID
Java 对象在序列化时,会自动生成一个序列化版本UID(serialVersionUID),它是一个64位的哈希码,用于标识对象的版本。当对象被反序列化时,Java 会比较传入对象的版本UID和类中声明的版本UID是否匹配,如果不匹配,将抛出 InvalidClassException
。
你可以显式地声明版本UID,以确保对象在类结构变化时仍然可以正确反序列化。例如:
private static final long serialVersionUID = 123456789L;
三、注意事项和最佳实践
-
序列化是 Java 中用于对象持久化的一种方式,但不适合所有情况。要慎重选择是否使用序列化,特别是在分布式系统中。
-
被序列化的类必须实现
Serializable
接口,而且要小心处理敏感信息,如密码等,不要序列化敏感数据。 -
在反序列化时,要确保类的版本和序列化时相同,否则可能会导致版本不匹配的问题。
-
序列化和反序列化可能会对性能产生一定的影响,因此在高性能要求的场景中要小心使用。
四、常见序列化协议
常见的序列化协议有很多,它们用于在不同的应用和平台之间序列化和反序列化数据。
-
Java 序列化(Java Serialization): Java 标准库中的序列化机制,用于将 Java 对象序列化为字节流,以便在不同 Java 应用之间进行数据传输和持久化。这种序列化方式使用
java.io.Serializable
接口。 -
JSON(JavaScript Object Notation): 一种轻量级的数据交换格式,易于阅读和编写。JSON 可以在不同的编程语言之间进行数据交换,广泛用于 Web 开发和 RESTful API。
-
XML(eXtensible Markup Language): 一种通用的标记语言,用于将结构化数据序列化为文本格式。XML 也可用于不同编程语言之间的数据交换,尤其在企业级应用中广泛使用。
-
Protocol Buffers(Protobuf): Google 开发的一种轻量级的二进制数据序列化协议,它具有高效的编解码性能和紧凑的数据表示。Protobuf 支持多种编程语言。
-
Apache Avro: 一种数据序列化框架,支持多种编程语言。Avro 使用 JSON 格式来定义数据结构,并可以将数据序列化为二进制格式。
-
Thrift: 由 Facebook 开发的一种跨语言的远程过程调用(RPC)框架,支持多种数据序列化格式,包括二进制、JSON 和 XML。
-
MessagePack: 一种高效的二进制序列化格式,通常用于在不同平台之间传输数据。它比 JSON 和 XML 更紧凑,解析速度更快。
-
CBOR(Concise Binary Object Representation): 一种二进制序列化格式,旨在与 JSON 兼容,但比 JSON 更紧凑和高效。
-
BSON(Binary JSON): 一种二进制 JSON 格式,主要用于 MongoDB 数据库的存储和交换。
-
Hessian 和 Burlap: 由 Caucho Technology 开发的一组二进制序列化协议,用于远程过程调用和数据交换。
这些序列化协议各有优点和适用场景,你可以根据项目的需求和技术栈来选择合适的协议。例如,如果需要高效的二进制序列化和跨语言支持,Protocol Buffers 或 MessagePack 可能是不错的选择;如果需要易读的数据交换格式,JSON 或 XML 可能更合适。
五、序列化协议对应于 TCP/IP 4 层模型
序列化协议通常不直接对应于 TCP/IP 4 层模型中的任何一层。TCP/IP 4 层模型包括以下层级:
-
应用层(Application Layer): 应用层协议负责定义应用程序之间的通信规则和数据交换格式。序列化协议通常在这一层中使用,以便将应用程序的数据序列化为可在网络上传输的格式。
-
传输层(Transport Layer): 传输层协议负责在网络上可靠地传输数据。TCP(传输控制协议)和UDP(用户数据报协议)是传输层协议的例子。序列化协议不属于传输层,但序列化后的数据可以通过传输层协议传输。
-
网络层(Network Layer): 网络层负责在不同网络之间路由数据包。IP(Internet Protocol)是网络层的核心协议。序列化协议通常不直接与网络层相关。
-
数据链路层(Data Link Layer): 数据链路层负责将数据帧从一个物理介质传输到另一个物理介质,通常与网络硬件相关。这一层与序列化协议无关。
序列化协议通常位于应用层,它定义了如何将应用程序中的数据序列化为可传输的格式,以及如何在接收端反序列化这些数据。然后,这些序列化后的数据可以使用传输层协议(如TCP或UDP)进行传输,以便在网络上进行数据交换。
六、serialVersionUID作用
serialVersionUID
是 Java 中用于序列化版本控制的一个特殊字段。它是一个静态常量,用于标识类的不同版本,以确保在反序列化过程中,序列化的类与反序列化的类具有兼容的版本。
serialVersionUID
的作用包括:
-
版本兼容性: 当类的结构发生变化(例如添加、删除或修改字段,或者改变继承关系)时,
serialVersionUID
可以确保在反序列化时不会导致版本不匹配的问题。如果反序列化时发现版本不匹配,会抛出InvalidClassException
。 -
允许反序列化旧版本: 如果你需要反序列化之前版本的对象,可以通过指定旧版本的
serialVersionUID
来实现。这允许你在升级应用程序时仍然能够处理旧版本的序列化数据。 -
避免不必要的异常: 如果没有明确指定
serialVersionUID
,Java 将根据类的结构自动生成一个版本号。但是,如果类的结构发生了变化,自动生成的版本号可能会导致不匹配的异常。通过显式设置serialVersionUID
,可以避免这种情况。
七、如果有些字段不想进行序列化怎么办
如果你希望某些字段不参与序列化,你可以使用 transient
关键字来标记这些字段。被 transient
修饰的字段不会被序列化,它们在序列化过程中会被忽略。当对象被反序列化时,这些字段会被赋予默认值。
以下是示例:
import java.io.Serializable;public class MyClass implements Serializable {private String name;private transient int age; // age 字段不会被序列化public MyClass(String name, int age) {this.name = name;this.age = age;}// 其他成员变量和方法
}
在上面的示例中,age
字段被标记为 transient
,这意味着在将 MyClass
对象序列化时,age
字段的值不会被包括在序列化数据中。当你反序列化 MyClass
对象时,age
字段会被赋予其默认值(0
对于 int
类型)。
使用 transient
关键字是一种常见的方式来控制哪些字段需要被序列化,哪些字段不需要。通常,不需要序列化的字段包括临时状态或不适合在序列化过程中传输的数据。例如,密码字段通常被标记为 transient
,以确保它们不会在网络传输或持久化到磁盘时泄漏。
相关文章:

面试系列 - 序列化和反序列化详解
Java 序列化是一种将对象转换为字节流的过程,可以将对象的状态保存到磁盘文件或通过网络传输。反序列化则是将字节流重新转换为对象的过程。Java 提供了一个强大的序列化框架,允许你在对象的持久化和网络通信中使用它。 一、Java 序列化的基本原理 Jav…...

基于Elasticsearch + Fluentd + Kibana(EFK)搭建日志收集管理系统
目录 1、EFK简介 2、EFK框架 2.1、Fluentd系统架构 2.2、Elasticsearch系统架构 2.3、Kibana系统架构 3、Elasticsearch接口 4、EFK在虚拟机中安装步骤 4.1、安装elasticsearch 4.2、安装kibana 4.3、安装fluentd 4.4、进入kibana创建索引 5、Fluentd配置介绍 VC常…...

【Python小项目之Tkinter应用】解决Python的Pyinstaller将.py文件打包成.exe可执行文件后文件过大的问题
文章目录 前言1. 创建新项目2.删除原项目中的全部文件3.将要打包的文件放入该项目目录下4.创建虚拟环境5.设置解释器为虚拟环境中的python解释器6.查看是否成功使用虚拟环境中的python解…...

Ab3d.DXEngine 6.0 Crack 2023
Ab3d.DXEngine 不是另一个游戏引擎(如Unity),它强迫您使用其游戏编辑器、其架构,并且需要许多技巧和窍门才能在标准 .Net 应用程序中使用。Ab3d.DXEngine 是一个新的渲染引擎,它是从头开始构建的,旨在用于标…...

Wireshark抓包常用指令
1.常用过滤规则 指定源地址: ip.src 10.0.1.123ip.src 10.0.1.123 && udphttp数据链路层:筛选mac地址为04:f9:38:ad:13:26的数据包----eth.src 04:f9:38:ad:13:26筛选源mac地址为04:f9:38:ad:13:26的数据包----eth.src 04:f9:38:ad:13:26网…...

Docker Swarm
Docker Swarm提供 Docker 容器集群服务,是 Docker 官方对容器云生态进行支持的核心方案。将多个 Docker 主机封装为单个大型的虚拟 Docker 主机,快速打造一套容器云平台。 Swarm mode内置 kv 存储功能,提供了众多的新特性,比如&a…...

jupyter notebook安装和删除kernel的解决方案
大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

中级深入--day16
爬虫(Spider),反爬虫(Anti-Spider),反反爬虫(Anti-Anti-Spider) 之间恢宏壮阔的斗争... Day 1 小黄想要某站上所有的电影,写了标准的爬虫(基于HttpClient库),不断地遍历某站的电影列表页面,根据 Html 分析电影名字存进…...

【洛谷 P1031】[NOIP2002 提高组] 均分纸牌 题解(贪心)
[NOIP2002 提高组] 均分纸牌 题目描述 有 N N N 堆纸牌,编号分别为 1 , 2 , … , N 1,2,\ldots,N 1,2,…,N。每堆上有若干张,但纸牌总数必为 N N N 的倍数。可以在任一堆上取若干张纸牌,然后移动。 移牌规则为:在编号为 1 …...

E5071C是德科技网络分析仪
描述 E5071C网络分析仪提供同类产品中最高的RF性能和最快的速度,具有宽频率范围和多功能。E5071C是制造和R&D工程师评估频率范围高达20 GHz的RF元件和电路的理想解决方案。特点: 宽动态范围:测试端口的动态范围> 123 dB(典型值)快速测量速度:41毫秒全2端口…...

ViTPose+:迈向通用身体姿态估计的视觉Transformer基础模型 | 京东探索研究院
身体姿态估计旨在识别出给定图像中人或者动物实例身体的关键点,除了典型的身体骨骼关键点,还可以包括手、脚、脸部等关键点,是计算机视觉领域的基本任务之一。目前,视觉transformer已经在识别、检测、分割等多个视觉任务上展现出来…...

Android 播放mp3文件
1,在res/raw中加入mp3文件 2,实现播放类 import android.content.Context; import android.media.AudioManager; import android.media.SoundPool; import android.util.Log;import java.util.HashMap; import java.util.Map;public class UtilSound {pu…...

在OpenStack私有云上安装配置虚拟机
文章目录 零、学习目标一、登录大数据实训云二、创建网络三、创建路由四、添加接口五、创建端口六、添加安全组规则七、创建实例(一)实例规划(二)创建实例 - ied(三)创建实例 - master、slave1与slave2&…...

pyCharm远程DEBUG
第一步,添加一个远程机器的解释器 ssh 远程机器解释器添加, 我本地ssh有配置目标机器。 如果没配置,那就选着new server configuration 新增一个。 interpreter 指定远程机器python, (机器上有多个版本python里尤其要…...

微服务框架Go-kit
微服务框架Go-kit go kit简介第一个go kit应用go kit基本概念go kit Endpointsgo kit Endpoint 定义go kit Endpoint 函数签名go kit Endpoint 链式操作go kit Endpoint 请求和响应转换go kit Endpoint 中间件go kit Endpoint 错误处理go kit 传输层go kit HTTP 传输层go kit …...

《王道24数据结构》课后应用题——第三章 栈和队列
第三章 【3.1】 03、 假设以I和O分别表示入栈和出操作。栈的初态和终态均为空,入栈和出栈的操作序列可表示为仅由I和O组成的序列,可以操作的序列称为合法序列,否则称为非法序列。 如IOIIOIOO 和IIIOOIOO是合法的,而IOOIOIIO和II…...

查看linux开发板的CPU频率
1)查看CPU可设置的频率列表 cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies 2)查看CPU当前所使用的频率: cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq 3)设置CPU频率(最高…...

对象模型和this指针(个人学习笔记黑马学习)
1、成员变量和成员函数 #include <iostream> using namespace std; #include <string>//成员变量和成员函数分开存储class Person {int m_A;//非静态成员变量 属于类的对象上的static int m_B;//静态成员变量 不属于类的对象上void func() {} //非静态成员函数 不…...

SpringCloudAlibaba常用组件
SpringCloudAlibaba常用组件 微服务概念 1.1 单体、分布式、集群 单体 ⼀个系统业务量很⼩的时候所有的代码都放在⼀个项⽬中就好了,然后这个项⽬部署在⼀台服务器上就 好了。整个项⽬所有的服务都由这台服务器提供。这就是单机结构。 单体应⽤开发简单,部署测试…...

Shotcut for Mac:一款强大而易于使用的视频编辑器
随着数码相机的普及,视频编辑已成为我们日常生活的一部分。对于许多专业和非专业用户来说,找到一个易于使用且功能强大的视频编辑器是至关重要的。今天,我们将向您介绍Shotcut——一款专为Mac用户设计的强大视频编辑器。 什么是Shotcut&…...

【数学建模】2023数学建模国赛C题完整思路和代码解析
C题第一问代码和求解结果已完成,第一问数据量有点大,经过编程整理出来了单品销售额的汇总数据、将附件2中的单品编码替换为分类编码,整理出了蔬菜各品类随着时间变化的销售量,并做出了这些疏菜品类的皮尔森相关系数的热力图&#…...

论数据库的种类
摘要 数据库是现代信息管理和数据存储的重要工具,几乎在各个领域都有广泛应用。不同类型的数据库适用于不同的应用场景和需求。本文将介绍几种常见的数据库种类,并探讨它们的特点和适用范围。 正文 一、关系型数据库(RDBMS) 关…...

docker笔记4:高级复杂安装-mysql主从复制
1.主从搭建步骤 1.1新建主服务器容器实例3307 docker run -p 3307:3306 --name mysql-master \ -v /mydata/mysql-master/log:/var/log/mysql \ -v /mydata/mysql-master/data:/var/lib/mysql \ -v /mydata/mysql-master/conf:/etc/mysql \ -e MYSQL_ROOT_PASSWORDroot \ -d…...

MySQL卸载干净再重新安装【Windows】
家人们,谁懂啊? 上学期学的数据库,由于上学期不知道为什么抽风,过得十分的迷,上课跟老师步骤安装好了Mysql,但后面在使用的过程中出现了问题,而且还出现了忘记密码这么蠢的操作,后半…...

在VScode中如何将界面语言设置为中文
VSCode安装后的默认界面是只有英文的,如果想用中文界面,那么就需要安装对应的插件,vscode插件可以从扩展中心去搜索并安装。 安装vscode后打开vscode,点击左侧的扩展按钮。 在搜索框中输入chinese,弹出chinese&#x…...

jenkins如何请求http接口及乱码问题解决
文章目录 1.插件安装2.请求pipline语法3.插件方式实现4.乱码问题解决5.值得注意 1.插件安装 需要安装HTTP Request 插件;安装方式不介绍。 2.请求pipline语法 官网链接,上面有详细语法:https://plugins.jenkins.io/http_request/ 附一个d…...

景区洗手间生活污水处理设备厂家电话
诸城市鑫淼环保小编带大家了解一下景区洗手间生活污水处理设备厂家电话 MBR生活污水处理设备构造介绍: mbr一体化污水处理的设计主要是对生活污水和相类似的工业有机污水的处理,其主要处理手段是采用目前较为成熟的生化处理技术接触氧化法,水…...

Java基础(四)
151. LinkedList特征分析 增删快 可以打断连接,重新赋值引用,不 涉及数据移动操作,效率高 查询慢 双向链表结构数据存储非连 续,需要通过元素一一 跳转 152 ArrayList和LinkedList对比分析 ArrayList特征 查询快。增删慢 适用于数据产出之…...

Android WIFI工具类 特别兼容Android12
直接上代码: package com.realtop.commonutils.utils;import android.annotation.SuppressLint; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothProfile; import android.content.Con…...

【Android Framework系列】第14章 Fragment核心原理(AndroidX版本)
1 简介 Fragment是一个历史悠久的组件,从API 11引入至今,已经成为Android开发中最常用的组件之一。 Fragment表示应用界面中可重复使用的一部分。Fragment定义和管理自己的布局,具有自己的生命周期,并且可以处理自己的输入事件。…...