Java 序列化

Java 序列化

  • 标记接口
  • transient(转瞬即逝的)
  • Java 序列化常用 API
  • serialVersionUID
  • writeReplace

序列化机制可以让对象地保存到硬盘上,减轻内存压力的同时,也起了持久化的作用;也可以让 Java 对象在网络传输。一般我们可以使用 java 自带的序列化机制和 json 来就行序列化。以下讲解一下序列化相关概念

标记接口

标记接口有时也叫标签接口(Tag interface),即接口不包含任何方法。在 Java 里很容易找到标记接口的例子,比如 JDK 里的 Serializable 接口就是一个标记接口。当然这个标记不是给人类看的,是给 java 虚拟机看的

标记接口是计算机科学中的一种设计思路。编程语言本身不支持为类维护元数据。而标记接口则弥补了这个功能上的缺失——一个类实现某个没有任何方法的标记接口,实际上标记接口从某种意义上说就成为了这个类的元数据之一。运行时,通过编程语言的反射机制,我们就可以在代码里拿到这种元数据

以 Serializable 接口为例。一个类实现了这个接口,说明它可以被序列化。因此,我们实际上通过 Serializable 这个接口,给该类标记了可被序列化的元数据,打上了可被序列化的标签。这也是标记/标签接口名字的由来,而其实现是在使用的时候校验是否实现了这个接口
在这里插入图片描述

注意如果子类实现了序列化,父类没有实现序列化,父类中的字段会丢失问题

标记接口多用坐实现某种功能的时候的校验,比如 Cloneable 会在对象进行复制的时候校验该类是否实现,Serializable 则是序列化的时候会做校验

transient(转瞬即逝的)

被该关键字修饰的变量(该关键字不能修饰方法或者类)不可以被序列化,只能存在于本地的内存中,最简单的例子就是不可以被 IO 输出到磁盘中,同样不能被远程传输。所修饰的变量如果是用户自定义类变量,则该类需要实现 Serializable 接口

顺便说一下,一个静态变量不管是否被 transient 修饰,均不能被序列化

还有一个例外,该类如果实现了 Externalizable(部化的)接口,可以调用 writeExternal 来指定序列化的对象,就算该对象被 transient 修饰也可以强制序列化

Java 序列化常用 API

java.io.ObjectOutputStream
java.io.ObjectInputStream
java.io.Serializable
java.io.Externalizable

ObjectOutputStream 表示对象输出流,它的 writeObject(Object obj) 方法可以对指定 obj 对象参数进行序列化,再把得到的字节序列写到一个目标输出流中。ObjectInputStream 则与之相反

Externalizable 继承了 Serializable 接口,还定义了两个抽象方法:writeExternal 和 readExternal,如果开发人员使用 Externalizable 来实现序列化和反序列化,需要重写 writeExternal 和 readExternal 方法。Externalizable 提供的方法让我们可以控制 Java 的序列化机制, 不依赖于 Java 的默认序列化

serialVersionUID

serialVersionUID 表面意思就是序列化版本号 ID,其实每一个实现 Serializable 接口的类,都有一个表示序列化版本标识符的静态变量,或者默认等于1L,或者等于对象的哈希码

JAVA 序列化的机制是通过判断类的 serialVersionUID 来验证版本是否一致的。在进行反序列化时,JVM 会把传来的字节流中的 serialVersionUID 和本地相应实体类的 serialVersionUID 进行比较,如果相同,反序列化成功,如果不相同,就抛出 InvalidClassException 异常

writeReplace

如果一个序列化类中含有 Object writeReplace() 方法,那么实际序列化的对象将是作为 writeReplace 方法返回值的对象,而且序列化过程的依据是实际被序列化对象的序列化实现

People 定义了 writeReplace 方法,并且自定义了 writeObject/readObject 方法

package com.soecode.lyf.demo.test.io;import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;public class People implements Serializable
{/****/private static final long serialVersionUID = 2659082826995480601L;private int age;private String name;People(int age,String name){this.age = age;this.name = name;}private void writeObject(ObjectOutputStream out){System.out.println("是否调用了我?");}private void readObject(ObjectInputStream in){System.out.println("是否调用了我?");}//在执行out.write()方法时会出发这个方法,先调用writeReplace// 如果没有writeReplace那么将会调用writeObject方法private Object writeReplace(){System.out.println("调用了 writeReplace()方法");return new Kong("路人");}}

如果报了这个错误,很有可能是对象实现了 writeReplace 方法,可以尝试切换一个对象,比如使用 Lists.newArrayList(orderNos) 来生成一个新对象

Unable to make private java.lang.Object java.util.Collections$UnmodifiableRandomAccessList.writeReplace() accessible: module java.base does not "opens java.util" to unnamed module @26ccba8f

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

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

相关文章

Java多态

多态 什么事多态: 同类型的对象表现出的不同的形态 多态的表现形式: 父类类型 对象名称子类对象; 满足多态的前提: 1.有继承或者实现的关系 2.有父类对象引用指向子类对象 (父类 变量名 new 子类(&#…

【MySQL索引特性】

文章目录 1. 没有索引,可能会有什么问题2. 认识磁盘2.1 MySQL与存储2.2 先来研究一下磁盘:2.3 磁盘随机访问(Random Access)与连续访问(Sequential Access) 3. MySQL 与磁盘交互基本单位4. 建立共识5. 索引的理解5.1 建立测试表5.2 插入多条记录5.3 查看…

【C++干货铺】C++中的四种类型转换

个人主页点击直达:小白不是程序员 C系列专栏:C干货铺 代码仓库:Gitee 目录 C语言中的类型转换 为什么C需要四种类型转化 C强制类型转换 static_cast reinterpret_cast const_cast dynamic_cast RTTI C语言中的类型转换 在C语言中&…

k8s部署Ingress

前提:有自备的域名,没有域名可用主机配置的域名解析代替测试 #主机配置的域名 vi /etc/hosts #追加以下内容 127.0.0.1 kuboard1、部署Ingress vi deploy.yaml #输入以下内容apiVersion: v1 kind: Namespace metadata:labels:app.kubernetes.io/instan…

第137期 Oracle的数据生命周期管理(20240123)

数据库管理137期 2024-01-23 第137期 Oracle的数据生命周期管理(20240123)1 ILM2 Heat Map3 ADO4 优点5 对比总结 第137期 Oracle的数据生命周期管理(20240123) 作者:胖头鱼的鱼缸(尹海文) Orac…

Zookeeper架构系列——集群模式

背景 架构图 集群模式详解 客户端连接到单个ZooKeeper服务器。客户端维护一个TCP连接,通过该连接发送请求、获取响应、获取监视事件和发送检测信号。如果与服务器的TCP连接中断,客户端将连接到其他服务器。 订购了ZooKeeper。ZooKeeper在每次更新时都…

微信小程序之全局配置-window和tabBar

学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您: 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持,想组团高效学习… 想写博客但无从下手,急需…

JS进阶-深入对象(二)

拓展:深入对象主要介绍的是Js的构造函数,实例成员,静态成员,其中构造函数和Java种的构造函数用法相似,思想是一样的,但静态成员和实例成员和java种的有比较大的差别,需要认真理解 • 创建对象三…

CHS_04.2.2.3_2+调度器和闲逛进程

CHS_04.2.2.3_2调度器和闲逛进程 调度器/调度程序(scheduler)闲逛进程 调度器/调度程序(scheduler) 调度器 或者叫调度程序 很简单的一个概念 调度程序是操作系统内核的一个非常非常重要的一个程序模块 我们说一个进程会在就绪运…

建议CSDN不要这样吃人xue馒头

程序员裁员潮:技术变革下的职业危机 2023年以来,谷歌、阿里巴巴各个科技公司都在裁员,程序员的日子也不好过。 讨论在技术变革下,裁员对于程序员的影响到底有多大,是非常有意义的话题,但是为什么要用“一…

Vulnhub-dc5

靶场下载 https://download.vulnhub.com/dc/DC-5.zip 信息收集 # nmap -sn 192.168.1.0/24 -oN live.port Starting Nmap 7.94 ( https://nmap.org ) at 2024-01-21 20:56 CST Nmap scan report for 192.168.1.1 (192.168.1.1) Host is up (0.00057s latency). MAC Address:…

《统计学习方法:李航》笔记 从原理到实现(基于python)-- 第1章 统计学习方法概论

文章目录 第1章 统计学习方法概论1.1 统计学习1.统计学习的特点2.统计学习的对象3.统计学习的目的4.统计学习的方法1.2.1 基本概念1.2.2 问题的形式化 1.3 统计学习三要素1.3.1 模型1.3.2 策略1.3.3 算法 1.4 模型评估与模型选择1…

零基础学Python(5)— 基本数据类型

前言:Hello大家好,我是小哥谈。在内存中存储的数据可以有多种类型。例如:一个人的姓名可以用字符型存储,年龄可以使用数值型存储,婚姻状况可以使用布尔型存储。这里的字符型、数值型、布尔型都是Python语言中提供的基本…

WorkPlus打造高效协作的即时通讯工具,提升工作效率

在当今互联网时代,高效沟通和协作是企业成功的关键要素。而即时通讯成为了实现快速沟通和实时协作的利器。作为一款领先的即时通讯工具,WorkPlus以其卓越的性能和独特的功能,助力企业实现高效的沟通和协作。 为什么选择WorkPlus作为即时通讯…

HCIP 交换

拓扑图&IP划分如下: 第一步,配制VLAN LSW1,LSW2&LSW3同理 检测 LSW1 LSW2 测试

2024年学鸿蒙开发有前途吗?

随着科技的不断发展和智能设备的普及,鸿蒙系统作为华为自主研发的操作系统,正逐渐受到市场的关注。2024年,学鸿蒙开发是否有前途,成为了很多开发者和学生关心的问题。本文将从多个角度分析鸿蒙系统的发展前景,以及学习…

【昕宝爸爸小模块】深入浅出之为什么POI的SXSSFWorkbook占用内存更小

➡️博客首页 https://blog.csdn.net/Java_Yangxiaoyuan 欢迎优秀的你👍点赞、🗂️收藏、加❤️关注哦。 本文章CSDN首发,欢迎转载,要注明出处哦! 先感谢优秀的你能认真的看完本文&…

初识SpringBoot

SpringBoot以约定大于配置的核心思想,默认帮我们进行了很多设置,简单来说就是SpringBoot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,spring boot整合了所有的框架 。 创建的包一定要在项目主程序入口…

容联七陌x新飞电器|升级高效智能客服,实现满意度跃升新台阶

随着电商兴起,电器行业深入到各大电子商务平台,订单量、咨询量也随之增长,对及时响应、准确回答、高效解决、提高服务品质等需求逐渐增加。 新飞电器选择了与容联七陌合作企业版在线客服产品,共同打造高效、便捷、个性化的优质客…

手把手教你使用MDK仿真调试

当今的嵌入式系统开发领域中,高效的调试工具对于工程师来说至关重要。它们能够极大地减少开发周期中的错误追踪时间,并加速产品的上市时间。MDK作为业界领先的嵌入式开发工具之一,其内置的调试功能被广大开发者所赞誉。这些功能不仅提供了对代…