Java序列化接口Serializable接口的作用总结

article/2025/9/5 0:52:52

一.Java序列化接口Serializable的作用:

一个对象有对应的一些属性,把这个对象保存在硬盘上的过程叫做”持久化”.  

对象的默认序列化机制写入的内容是:对象的类,类签名,以及非瞬态和非静态字段的值。(因为静态static的东西在方法区.)

序列化能把堆内存中的对象的生命周期延长,做持久化操作.当下次再需要这个对象的时候,我们不用new了,直接从硬盘中读取就可以了.(存储到硬盘是一个文件,不需要我们去解析,如果用记事本打开解析会出现乱码,解析要用特定的方式,不用我们管. 我们只需要读取).  把对象存储到硬盘上的一个文件中,这个文件的标准扩展名是(.object).

什么样的数据会进行序列化到硬盘进行持久化?

①在很多框架中就会有这种.object结尾的文件,因为很多对象都不创建,创建起来太麻烦,直接读取,而且有些对象的值你不知道,框架封存在.object文件中,直接读取这个文件中的这个值就行了,不需要传这个值.

在搞web开发的时候一些类就需要实现序列化接口,因为服务器就会对你的对象进行临时本地存储.它怕服务器崩了的以后,你的会话都被消失了.所以存储在了硬盘上,你重新启动服务器会恢复之前的会话,恢复对象,你之前运行的东西都在.

 

②对某些特点的对象,比如数据库连接对象,存储特定数据的对象 ,这样对象你不想创建他们,想存储起来,让他们的生命周期延长,可以把他们放在硬盘当中.每次系统启动的时候都到.object中读取对象和里面的数据,这个时候就可以把他们序列化来完成.

二.具体举例:

Person.java

复制代码

1 import java.io.Serializable;2 /*3  * Serializable:用于给被序列化的类加入ID号。4  * 用于判断类和对象是否是同一个版本。 5  */6 public class Person implements Serializable/*标记接口*/ {7     /**8      * transient:非静态数据不想被序列化可以使用这个关键字修饰。 9      */
10     private static final long serialVersionUID = 9527l; 
11 //    private transient String name;
12     private  String name;
13 //    private static int age;
14     private int age;
15 
16     public Person(String name, int age) {
17         super();
18         this.name = name;
19         this.age = age;
20     }
21     public String getName() {
22         return name;
23     }
24     public void setName(String name) {
25         this.name = name;
26     }
27     public int getAge() {
28         return age;
29     }
30     public void setAge(int age) {
31         this.age = age;
32     }
33 }

复制代码

ObjectStreamDemo.java

复制代码

1  public class ObjectStreamDemo {2      /**3       * @param args4       * @throws IOException 5       * @throws ClassNotFoundException 6       */7      public static void main(String[] args) throws IOException, ClassNotFoundException {8          //writeObj();9          readObj();
10      }
11      public static void readObj() throws IOException, ClassNotFoundException {
12          ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.object"));
13          //对象的反序列化。 
14          Person p = (Person)ois.readObject();
15          System.out.println(p.getName()+":"+p.getAge());
16          ois.close();
17      }
18  
19      public static void writeObj() throws IOException, IOException {
20          
21          ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.object"));
22          //对象序列化。  被序列化的对象必须实现Serializable接口。 
23          oos.writeObject(new Person("小强",30));
24          oos.close();
25      }
26  }

复制代码

 

上面的例子中当你一开始对这个person类进行序列化的时候用的是private类型序列化的,但是你在反序列化之前,把这个private改成了public.这样反序列化读取的时候就会报出异常.

Exception in thread "main" java.io.InvalidClassException: cn.itcast.serializable.Person; local class incompatible: stream classdesc serialVersionUID = 9527, local class serialVersionUID = 7915096815468332737

就是关于前后这个Person类的版本号不统一.如果加上设定一个版本号,那么经过上面的修改也是可以反序列化的.

可能抛出的错误 @throws ClassNotFoundException

如果只有obj.object 这个文件能不能把其中的对象Person取出来,因为任何对象在堆内存中创建都必须依赖于该对象所属的类文件(class文件),如果仅仅给了obj.object,这个里面有Person对象的字节码,可是取出的时候你内存中并没有Person.class文件,没有,所以取不出来,所以必须要有obj.object文件和Person.class文件.(所以有一个ClassNotFound异常)

关于程序中的类 ObjectInputStream和ObjectOutputStream 

ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化(意思就是ObjectInputStream只能读取ObjectOutputStream的)

ObjectOutputStream 和 ObjectInputStream 分别与 FileOutputStream 和 FileInputStream 一起使用时,可以为应用程序提供对对象的持久存储。

关于SerializableID

SerializableID号是根据类的特征和类的签名算出来的.为什么ID号那么长,是因为为了避免重复.所以Serializable是给类加上id用的. 用于判断类和对象是否是同一个版本。

如果可序列化类未显式声明 serialVersionUID,则序列化运行时将基于该类的各个方面计算该类的默认 serialVersionUID 值. 原因是计算默认的 serialVersionUID 对类的详细信息具有较高的敏感性,根据编译器实现的不同可能千差万别,这样在反序列化过程中可能会导致意外的 InvalidClassException

序列化接口的i

序列化Serializable的方式特别简单 实现Serializable接口,再在类中声明如下这一个属性即可。

private static final long serialVersionUID = -3928832861296252415L;

Serializable序列化的工作机制:

序列化的时候系统会把当前类的serialVersionUID 写入序列化的文件中(也可能是其他中介),当反序列化的时候系统会去检测文件中的serialVersionUID ,看它是否和当前类的serialVersionUID 一致,如果一致就说明序列化的类的版本和当前类的版本是相同的,这个时候可以成功反序列化,否则就说明当前类和序列化的类相比发生了某些变换,比如成员变量的数量,类型可能发生了改变,这个时候就会抛异常,反序列化失败。

serialVersionUID作用: 
序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。 

那么serialVersionUID 是如何生成,生成规则是怎么样的呢?

默认情况下,也就是不声明serialVersionUID 属性情况下,系统会按当前类的成员变量计算hash值并赋值给serialVersionUID 。

所以,结论就出来了。声明serialVersionUID ,可以很大程度上避免反序列化过程的失败。比如当版本升级后,我们可能删除了某个成员变量,也可能增加了一些新的成员变量,这个时候我们的反序列化依然能够成功,程序依然能够最大程度地恢复数据,相反,如果不指定serialVersionUID ,程序就会挂掉。

 

如果类结构发生了非常规性改变,比如修改了类名,类型等,这个时候尽管serialVersionUID 验证通过了,但是反序列化过程

还是会失败,因为类结构有了毁灭性的改变。


http://chatgpt.dhexx.cn/article/JuMhAqq9.shtml

相关文章

serializable接口的作用是什么?

serializable接口的作用: 1、存储对象在存储介质中,以便在下次使用的时候,可以很快捷的重建一个副本; 2、便于数据传输,尤其是在远程调用的时候。 Serializable接口是启用其序列化功能的接口。实现java.io.Serializ…

Mapper 接口的如何起作用

在 MyBatis 的初始化过程中&#xff0c;每个一个 XML 映射文件中的<select />、<insert />、<update />、<delete />标签&#xff0c;会被解析成一个 MappedStatement 对像&#xff0c;对应的 id 就是 XML 映射文件配置的 namespace’.’statementId&a…

C#接口作用的深入理解

原文出处&#xff1a; 指尖流淌-吴学雷 1、C#接口的作用 C# 接口是一个让很多C#初学者容易迷糊的东西&#xff0c;用起来好像很简单&#xff0c;定义接口&#xff0c;里面包含方法&#xff0c;但没有方法具体实现的代码&#xff0c;然后在继承该接口的类里面要实现接口的所有…

java接口的作用和意义_Java接口的作用与意义

接口 1.接口的特点 首先看下面的这个抽象类代码: 抽象类代码中变量全为常量,方法全是抽象方法,这样的形式,我们可以将它们定义为接口类,书写方式如下: 接口的语法为: interface接口名{常量或方法 } 接口特点: 所有的属性都是公开静态常量所有的方法都是公开抽象方法没有…

java接口有什么用_接口有什么作用

接口的作用:1、接口可以使项目分离,所有层都面向接口开发,提高开发效率;2、接口使代码和代码之间的耦合度降低;3、接口可以多实现,多继承,并且一个类除了接口之外,还可以继承其它类。 接口的作用: 1、可以使项目分离,所有层都面向接口开发,提高开发效率; 2、接口使…

Comparable接口作用

今天在开发中无意看到Integer包装类内部实现了Comparable接口&#xff0c;因此探查一下该接口作用&#xff1a; 查看API解释&#xff1a; 此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序&#xff0c;类的 compareTo 方法被称为它的自然比较方法。…

java接口的作用是什么?接口的使用规范介绍

你知道java接口的作用有哪些吗&#xff1f;java接口的使用规范又是怎样的呢&#xff1f;有哪些是需要我们注意的?下面一起来详细的了解一下吧。 java接口的作用是什么&#xff1f; 一、接口的作用 首先&#xff0c;我们来谈论一下java接口的作用吧! 简单的来说&#xff0c…

接口的作用

今日内容&#xff1a;接口概述、接口定义、接口的用法、接口的继承、接口和抽象类的区别。 1.概述 接口定义了实现某种功能的规范&#xff0c;用来扩展类的功能。接口并不是类&#xff0c;编写接口的方式和类很相似&#xff0c;但是它们属于不同的概念。类描述对象的属性和方法…

Pregel Master

转载于:https://www.cnblogs.com/fanweisheng/p/11269479.html

Pregel Combiner

转载于:https://www.cnblogs.com/fanweisheng/p/11269462.html

Pregel Aggregator

转载于:https://www.cnblogs.com/fanweisheng/p/11269466.html

Pregel Worker

转载于:https://www.cnblogs.com/fanweisheng/p/11269474.html

图计算-Pregel-Hama

一.图计算简介 1.1 图计算是专门针对图结构数据的处理&#xff0e; 许多大数据都是以大规模图或网络的形式呈现&#xff1b;许多非图结构的大数据&#xff0c;也常常被转换为图模型后进行分析&#xff1b;图结构很好地表达了数据之间的关联性&#xff1b;关联性计算是大数据计…

分布式图处理系统--Pregel

介绍分布式图处理系统–Pregel以及其开源实现–Giraph 图数据处理简介 图数据的应用 图数据 数据本身以图的形式呈现 社交网络传染病传播途径交通路网 某些非图结构的数据&#xff0c;也可以转换为图模型后进行处理 网页链接机器学习训练数据 关联性分析 图数据结构表达了…

graphx中Pregel函数详解

1、PregelAPI 图本质上是一种递归的数据结构&#xff0c;其顶点的属性值依赖于其邻接顶点&#xff0c;而其邻接顶点属性又依赖于其邻接顶点&#xff0c;许多重要的图算法通过迭代计算每个顶点的属性直到到达定点条件&#xff0c;这些迭代的图算法被抽象成一系列图并行操作。 2、…

Pregel与图迭代

graphx是如何实现Pregel迭代操作&#xff0c;我们应该如何使用该模型。先看下pregel接口源码&#xff1a; 接口中各参数的含义已在图中进行注释&#xff0c;所以此处不再赘述。简单介绍下源码中的参数说明&#xff1a; 剖析 pregel模型提供了消息收集方向、迭代次数、初始化消…

Google图算法引擎Pregel介绍

参考文献点击打开链接 【前言&#xff1a;有一种说法[1]是Google的程序里面80%用的是MapReduce&#xff0c;20%用的是Pregel。今天就来介绍一下这个Pregel。想要深入研究的同志们&#xff0c;可以参考最新的SIGMOD 2010 ppt[2]。】 简介 Pregel是一个用于分布式图计算的计算…

图计算: 使用 Spark Graphx Pregel API 处理分层数据

今天&#xff0c;分布式计算引擎是许多分析、批处理和流应用程序的支柱。Spark提供了许多开箱即用的高级功能&#xff08;pivot、分析窗口函数等&#xff09;来转换数据。有时需要处理分层数据或执行分层计算。许多数据库供应商提供诸如“递归 CTE&#xff08;公用表达式&#…

pregel 与 spark graphX 的 pregel api

[原文](https://blog.csdn.net/u013468917/article/details/51199808)简介 在Hadoop兴起之后&#xff0c;google又发布了三篇研究论文&#xff0c;分别阐述了了Caffeine、Pregel、Dremel三种技术&#xff0c;这三种技术也被成为google的新“三驾马车”&#xff0c;其中的Pregel…

Pregel体系结构

在Pregel计算框架中&#xff0c;一个大型图会被划分成许多个分区&#xff0c;每个分区都包含了一部分顶点以及以其为起点的边 一个顶点应该被分配到哪个分区上&#xff0c;是由一个函数决定的&#xff0c;系统默认函数为hash(ID) mod N&#xff0c;其中&#xff0c;N为所有分区…