Serializable是什么,为什么要实现Serializable接口?

Java基础篇-Serializable序列化详解 如果此时几个不同的服务之间要去共享同一个数据对象怎么办? 这时就要用到序列化了。以Java语言为例,我们都知道Java属于一门对象编程语言,它是与人交互的语言。但是二进制这种010101的数字属于机器语言,是与CPU做交互的。那么我们的Java对象要想被机器所理解,使其变成“二进制流”,这个转换编码的过程就叫做“序列化”。将二进制流转为Java对象的解码过程被称为“反序列化”。 阅读详情
AI摘要

本文介绍了Serializable接口的作用,序列化和反序列化的基本概念,以及在何时何地需要序列化对象。重点讲解了serialVersionUID的重要性,包括为何需要定义它以及其在类序列化中的角色。,

一般情况下,我们在定义实体类时会实现Serializable接口,例如

一、什么是Serializable接口

一个对象序列化的接口,一个类只有实现了Serializable接口,它的对象才能被序列化。

Serializable是java.io包中定义的、用于实现Java类的序列化操作而提供的一个语义级别的接口。

Serializable序列化接口没有任何方法或者字段,只是用于标识可序列化的语义。

实现了Serializable接口的类可以被ObjectOutputStream转换为字节流,同时也可以通过ObjectInputStream再将其解析为对象。例如,我们可以将序列化对象写入文件后,再次从文件中读取它并反序列化成对象,也就是说,可以使用表示对象及其数据的类型信息和字节在内存中重新创建对象。

二、什么是序列化?

序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。

三、为什么要序列化对象

把对象转换为字节序列的过程称为对象的序列化

把字节序列恢复为对象的过程称为对象的反序列化

序列化对于面向对象的编程语言来说是非常重要的,因为无论什么编程语言,其底层涉及IO操作的部分还是由操作系统其帮其完成的,而底层IO操作都是以字节流的方式进行的,所以写操作都涉及将编程语言数据类型转换为字节流,而读操作则又涉及将字节流转化为编程语言类型的特定数据类型。

四、什么情况下需要序列化?

当我们需要把对象的状态信息通过网络进行传输,或者需要将对象的状态信息持久化,以便将来使用时都需要把对象进行序列化。

那为什么还要继承Serializable。那是存储对象在存储介质中,以便在下次使用的时候,可以很快捷的重建一个副本。

或许你会问,我在开发过程中,实体并没有实现序列化,但我同样可以将数据保存到mysql、Oracle数据库中,为什么非要序列化才能存储呢?

我们来看看Serializable到底是什么,跟进去看一下,我们发现Serializable接口里面竟然什么都没有,只是个空接口

一个接口里面什么内容都没有,我们可以将它理解成一个标识接口。

比如在课堂上有位学生遇到一个问题,于是举手向老师请教,这时老师帮他解答,那么这位学生的举手其实就是一个标识,自己解决不了问题请教老师帮忙解决。在Java中的这个Serializable接口其实是给jvm看的,通知jvm,我不对这个类做序列化了,你(jvm)帮我序列化就好了。

Serializable接口就是Java提供用来进行高效率的异地共享实例对象的机制,实现这个接口即可。

五、为什么要定义serialversionUID变量

首先看一下接口里的说明:
在这里插入图片描述
可以发现如果我们不自定义serialversionUID,系统就会生成一个默认的serialversionUID。
在这里插入图片描述
从注释中我们可以看到,它强烈建议我们自己定义一个serialversionUID,因为默认生成的serialversionUID对class极其敏感,在反序列化的时候很容易抛出InvalidClassException异常。

六、序列化的使用

下面我们可以通过例子来实现将序列化的对象存储到文件,然后再将其从文件中反序列化为对象,代码示例如下:

先定义一个序列化对象User:

  public class User implements Serializable { 
        private static final long serialVersionUID = 1L; 
     
        private String userId; 
        private String userName; 
     
        public User(String userId, String userName) { 
            this.userId = userId; 
            this.userName = userName; 
        } 
    } 

然后我们编写测试类,来对该对象进行读写操作,我们先测试将该对象写入一个文件:

 public class SerializableTest { 
     
        /** 
         * 将User对象作为文本写入磁盘 
         */ 
        public static void writeObj() { 
            User user = new User("1001", "Joe"); 
            try { 
                ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("/Users/guanliyuan/user.txt")); 
                objectOutputStream.writeObject(user); 
                objectOutputStream.close(); 
            } catch (IOException e) { 
                e.printStackTrace(); 
            } 
        } 
     
        public static void main(String args[]) { 
            writeObj(); 
        } 
    } 

运行上述代码,我们就将User对象及其携带的数据写入了文本user.txt中。

接下来,我们继续编写测试代码,尝试将之前持久化写入user.txt文件的对象数据再次转化为Java对象,代码如下:

public class SerializableTest {
    /**
     * 将类从文本中提取并赋值给内存中的类
     */
    public static void readObj() {
        try {
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("/Users/guanliyuan/user.txt"));
            try {
                Object object = objectInputStream.readObject();
                User user = (User) object;
                System.out.println(user);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void main(String args[]) {
        readObj();
    }
}

通过反序列化操作,可以再次将持久化的对象字节流数据通过IO转化为Java对象,结果如下:

cn.wudimanong.serializable.User@6f496d9f

序列化与反序列化操作过程就是这么的简单。只需要将User写入到文件中,然后再从文件中进行恢复,恢复后得到的内容与之前完全一样,但是两者是不同的对象。

七、关于serialVersionUID

对于JVM来说,要进行持久化的类必须要有一个标记,只有持有这个标记JVM才允许类创建的对象可以通过其IO系统转换为字节数据,从而实现持久化,而这个标记就是Serializable接口。而在反序列化的过程中则需要使用serialVersionUID来确定由那个类来加载这个对象,所以我们在实现Serializable接口的时候,一般还会要去尽量显示地定义serialVersionUID。

这个serialVersionUID的详细的工作机制是:在序列化的时候系统将serialVersionUID写入到序列化的文件中去,当反序列化的时候系统会先去检测文件中的serialVersionUID是否跟当前的文件的serialVersionUID是否一致,如果一直反序列化不成功,就说明当前类跟序列化后的类发生了变化,比如是成员变量的数量或者是类型发生了变化,那么在反序列化时就会发生crash,并且回报出错误:

java.io.InvalidClassException: User; local class incompatible: stream classdesc serialVersionUID = -1451587475819212328, local class serialVersionUID = -3946714849072033140at 
java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:699)at 
java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1885)at 
java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1751)at
java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2042)at 
java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)at 
java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)at 
Main.readUser(Main.java:32)at Main.main(Main.java:10)

刚开始提到了,serialVersionUID要不要指定呢?如果不指定会出现什么样的后果?如果指定了以后后边的值又代表着什么意思呢?既然系统指定了这个字段,那么肯定是有它的作用的。

如果我们在序列化中没有显示地声明serialVersionUID,则序列化运行时将会根据该类的各个方面计算该类默认的serialVersionUID值。但是,Java官方强烈建议所有要序列化的类都显示地声明serialVersionUID字段,因为如果高度依赖于JVM默认生成serialVersionUID,可能会导致其与编译器的实现细节耦合,这样可能会导致在反序列化的过程中发生意外的InvalidClassException异常。因此,为了保证跨不同Java编译器实现的serialVersionUID值的一致,实现Serializable接口的必须显示地声明serialVersionUID字段。

此外serialVersionUID字段地声明要尽可能使用private关键字修饰,这是因为该字段的声明只适用于声明的类,该字段作为成员变量被子类继承是没有用处的!有个特殊的地方需要注意的是,数组类是不能显示地声明serialVersionUID的,因为它们始终具有默认计算的值,不过数组类反序列化过程中也是放弃了匹配serialVersionUID值的要求。

我用 Claude Code 给 Spring Boot 老项目做了一次代码 Review:查出 4 类隐藏问题 接手 Spring Boot 老项目时,真正麻烦的往往不是编译报错,而是分散在业务代码中的空指针、N+1 查询、异常吞没和并发隐患。本文记录一次使用 Claude Code 辅助代码 Review 的完整流程,并给出提示词、Java 示例、修改方案和人工复核方法。 阅读详情

相关推荐

ZBrush 2021来了

这次给大家带来的是:zbrush2021.1.1 win安装教程 1.下载压缩包之后解压到文件夹当中,然后打开ZBrush_2021_Installer.exe进行软件安装, 如下图 2.在这里我们保持默认的简体中文版即可,然后点击确认,如下图 3.第三步我们点击前进即可,如下图 4.第四步我们来到许可协议,在这里我们点击我接受此协议,然后点击前进,如下图 5.第五步我们来到安装目录,在这里我们可以设置安装路径,如下图 6.在这里我将安装目录修改安装到E盘为例,然后点击下一

3D游戏建模 1188

java接口之 Serializable

最近在阅读JDK源码中的集合,看到很多集合类实现了Serializable接口,Cloneable接口。在阅读了很多关于Serializable接口的博客后,浅谈下我对Serializable接口的理解。 序列化 查看 官方文档 就会发现 Serializable接口中一个成员函数或者成员变量也没有。那么这个接口的作用是什么呢。网上找了一些博客看过之后,知道这个接口的作用是实现序列化。 序列化:对象的寿命通常随着生成该对象的程序的终止而终止,有时候需要把在内存中的各种对象的状态(也就是实例变量,不是方法.

鱼的博客 1369

忘记安卓锁屏密码怎么办?3种方法教你用ADB恢复访问(含gesture.key解密)

本文详细解析了安卓设备锁屏密码的存储与加密机制,特别是gesture.key文件的解密原理。针对遗忘密码的常见问题,提供了三种核心恢复方法:利用ADB调试接口删除密码文件、对gesture.key进行离线分析与解密,以及应对高版本系统的替代方案。重点介绍了通过ADB工具在Recovery模式下操作的具体步骤,帮助用户在合法合规前提下恢复设备访问权限。

php55的博客 959

Serializable简单介绍

对Serializable简单介绍

TRK_YX的博客 4785

基于yolo11的BGA图像目标检测

15.YOLOv8的n/s版本(如YOLOv8n-1280),或通过TensorRT量化压缩模型。3.使用自适应batch_size(如根据GPU显存动态调整),推荐16-32。为采集分辨率整数倍(如原图2592×1944,训练时缩放为640×480),保持宽高比。14.采用余弦退火学习率(cos_lr)和早停(patience=50),防止过拟合。1.模型标注后,少量标注全部人工校验,大量数据抽检,部分人工检验。13.部署模型后持续收集困难样本(如模棱两可的预测结果),定期迭代更新模型。

qq_47798402的博客 1205

线性代数——(期末突击)行列式(上)-行列式计算、行列式的性质

简单解释一下:4213原本的顺序应为1234,对于‘4’而言,‘2’、‘1’、‘3’都应该排在它的前面,所以此处记逆序数为3;对于‘2’而言,‘1’应该排在它的前面,而‘3’排在它之后 是合理的,所以此处只有一个逆序数;最后看‘1’,其后面的‘3’排在后面显然也是合理的,故而4213的逆序数为4.一般我们使用这个性质来计算四阶行列式,也就是将其变换成三角行列式,再计算对角线的值;以主对角线为分界线的就为正三角,反之则为反三角行列式。若行列式某一行(列)为0,则该行列式=0.将和的那一行分开,其余行。

li13437542099的博客 1万+

Serializable接口分析

开发中遇到过很多实现Serializable接口的类,也会很迷惑这个接口不提供任何变量和方法,最近有时间就来深挖一下Serializable吧Serializable接口的作用是实现序列化 序列化:对象的寿命通常随着生成该对象的程序的终止而终止,有时候需要把在内存中的各种对象的状态(也就是实例变量,不是方法)保存下来,并且可以在需要时再将对象恢复。虽然你可以用你自己的各种各样的方法来保存对象的状态,但是Java给你提供一种应该比你自己的好的保存对象状态的机制,那就是序列化系列化的用途代码如下(示例): 控制

ZHI_YUE的博客 8950

软考嵌入式 第五讲 嵌入式Linux系统技术

5.1 inittab配置文件 Linux实时操作系统开机引导时首先启动内核,由内核检查和初始化硬件设备,载入设备的驱动程序模块,安装root文件系统,然后内核将启动一个名为init的进程,它是系统运行的第一个进程,进程号为1。在init运行完成并启动其他必要的后续进程后,系统开始运行,引导过程结束。 在任何时候,可以在文件inittab中添加新的记录项。重新检查inittab文件时,可以通过命令:init q/ Q使init进程立即重新读取并处理文件inittab。 5.1.1 inittab文件记录

Leon的博客 526

【Serializable原理】Serializable的使用

持久化”意味着对象的“生存时间”并不取决于程序是否正在执行——它存在或“生存”于程序的每一次调用之间。通过序列化一个对象,将其写入磁盘,以后在程序再次调用时重新恢复那个对象,就能圆满实现一种“持久”效果。

wufaqidong1的博客 2292

Python爬虫实战:利用最新技术高效爬取百度贴吧帖子内容

本文将详细介绍如何使用Python最新技术栈构建一个高效的百度贴吧爬虫,包括requests-html异步请求、BeautifulSoup4解析、数据存储到MongoDB以及应对反爬机制等完整解决方案。文章包含5000余字详细教程和完整代码实现。网络爬虫(Web Crawler)是一种自动获取网页内容的程序,广泛应用于搜索引擎、数据分析和内容聚合等领域。Python凭借其丰富的库生态系统成为爬虫开发的首选语言。贴吧作为中文互联网最大的兴趣社区,包含大量有价值的UGC内容。动态加载内容处理登录状态维持。

2201_76125261的博客 541

基于STM32设计的太阳能智慧路灯_444

本文设计并实现了一种基于 STM32 的太阳能智慧路灯系统。系统以 STM32F103C8T6 单片机为核心,集成温湿度检测、空气质量检测、环境光照检测、行人检测和路灯故障检测等功能,实现对路灯运行环境和工作状态的实时感知。

462

为什么要实现Serializable接口

首先说明Serializable主要作用将类的实例持久化保存,序列化就是保存,反序列化就是读取。保存也不一定保存在本地,也可以保存到远方。 工作中我们经常在进行持久化操作和返回数据时都会使用到javabean来统一封装参数,方便操作,一般我们也都会实现Serializable接口,那么问题来了,首先:为什么要进行序列化;其次:每个实体bean都必须实现serializabel接口吗?最后:我做一些...

小太阳啊凯的博客 639

OpenMVS :用 colmap制作自己的数据集 重建(用colmap计算位姿,将位姿转为MVS需要的格式)

数据集制作主要是在windows进行,比较方便。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 3326

为什么实体类要实现serializable接口 序列化

为什么实体类要实现serializable接口 序列化 最重要的两个原因是:   1、将对象的状态保存在存储媒体中以便可以在以后重新创建出完全相同的副本;   2、按值将对象从一个应用程序域发送至另一个应用程序域。    实现serializable接口的作用是就是可以把对象存到字节流,然后可以恢复。所以你想如果你的对象没实现序列化怎么才能进行网络传输呢,要网络传输就得转为字节流,所以在分布式应用中,你就得实现序列化,如果你不需要分布式应用,那就没那个必要实现序列化。 implements Serializ

葬爱家族专注于葬送java 2278

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

实体类 实现 Serializable到底有什么用呢?每个实体类基本上都要实现这个Serializable接口

实体类 实现序列化接口 Serializable 一般情况下,我们在定义实体类时会继承Serializable接口,类似这样: 我们在实体类中引用了Serializable这个接口,那么这个接口到底有什么?细心的你会发现我们还定义了个serialVersionUID变量。这个变量到底有什么作用? 什么是Serializable接口 一个对象序列化的接口,一个类只有实现了Serializable接...

冯安晨 8958

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

没有任何东西的 Serializable 接口, 为什么实现这个接口就可以序列化

我们可以看一下Serializable 接口 发现这个接口啥都没有。 先写一个测试例子: import java.io.Serializable; public class User implements Serializable { private static final long serialVersionUID = 1L; private String name; private String sex; private Integer age;..

墨 尘 939

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

serializable接口_提示实现serializable接口

API 第 1 步:安装GenerateSerialVersionUID插件如上图所示,点击Preferences,进入如下界面:在这里,选择Plugins,并搜索GenerateSerialVersionUID,如果没有发现此插件,则可以点击Search in repositories进行搜索:如上图所示,点击install,即可安装此插件。第 2 步:设置Inspections功能如上图所示,...

weixin_39646405的博客 286

为什么Java集合类没有实现Cloneable和Serializable接口

这种设计保持了集合的灵活性,同时避免了潜在的深拷贝和序列化问题。,并不是所有集合都需要序列化,强制所有集合支持序列化不符合设计原则。所有集合都会默认支持序列化,但如果元素不可序列化,就会导致。,不同集合的克隆方式不同,不适合在接口中定义。这样,开发者可以根据具体需求决定是否需要克隆。主要是实现细节,放在具体的子类中更合理。,接口应当只定义核心行为,而非实现细节,可能不需要序列化,而数据库查询结果的。的实现留给具体的子类,而不是强加在。这样,只有需要序列化的集合才实现。,并不是所有集合都需要序列化。

x² 1249

为什么要实现Serializable序列化接口

Java中为什么要实现序列化接口 我们在学习JavaSE的时候学习过ObjectInputStream和ObjectOutputStream,当时是觉得只要一个对象要写入文件就必须要实现Serializable接口。其实这样理解完全没有问题 一、问题引入 Java中为什么要实现序列化接口呢?我们来看下图: Java程序中要往磁盘中写入一个数据,这个数据如果是一个普通字符串,那么没有问题,所有机器...

緑水長流*z 1218

java实现comparable接口_Java--类为什么实现Serializable接口

学神请坐,听我慢慢道来!背景:一个java中的类只有实现了Serializable接口,它的对象才是可序列化的。如果要序列化某些类的对象,这些类就必须实现Serializable接口。Serializable是一个空接口,没有什么具体内容,它的目的只是简单的标识一个类的对象可以被序列化。为什么要进实现Serializable接口:为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可...

weixin_39670857的博客 349

serializable接口_探讨为什么实现Serializable接口就可以序列化

在探讨这个问题之前小编先上个概念。什么是序列化和反序列化呢?序列化就是指把Java对象转换为字节流写入硬盘的过程。public static void writeObject(Object obj, String dstFilePath) throws IOException { ObjectOutputStream out = new ObjectOutputStream(new File...

weixin_39722025的博客 99

实现Serializable接口

Serializable接口:该接口仅仅是一个标记接口,无任何方法定义。 当一个类实现了Serializable接口表示该类可序列化。序列化是将一个实现Serializable接口的对象转化成一个字节序列(一组byte)。可以把该字节序列保存起来,以后要用这个对象时候,就能把这些byte数据恢复出来,并据此重新构建那个对象。甚至可以将该字节序列放到其他计算机上或者通过网络传输到其他计算机上恢复,只

白净垃圾桶- 1475

第86项:谨慎地实现Serializable接口

  要想使一个类的实例可被序列化,非常简单,只要在它的声明中假如“implemants Serializable”字样即可。正因为太容易了,所以普遍存在这样一种误解,认为程序猿可以毫不费力就可以实现序列化。实际情形要复杂得多。虽然使一个类可序列化的直接成本可以忽略不计,但长期的成本通常是很高的。   实现Serializable接口而付出的最大代价是,一旦一个类被发布,就大大降低了“改变这个类的实...

Coloured_Glaze的博客 721

Java 实现序列化接口 Serializable

java对象实现Serializable接口 Serializable接口在JDK1.1开始声明 所在包为java.io中,仅声明为一个接口,并没有任何方法。 1.序列化和反序列化 (1)Java序列化是指把Java对象转换为字节序列的过程,而Java反序列化是指把字节序列恢复为Java对象的过程; (2)序列化:对象序列化的最主要的用处就是在传递和保存对象的时候,保证对象的完整性和可传...

weixin_39509830的博客 8566

浅谈实体类为什么要实现Serializable接口?

序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象;序列化保存对象转态,不保存静态变量。 三种情况: 1. 将对象存储在硬盘上。 2. 将对象通过网络传输。 3. 通过RMI远程调用等方式传输对象的时候。 在这三种情况下,是需要进行...

jdnicky的博客 4189
上一篇: MyBatis的原始Dao开发
下一篇: 使用switch语句为考试分数分级
今天的接口写完了吗?
博客等级 码龄5年 2215粉丝 412原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今天的接口写完了吗?

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值