nodejs做静态网站,中国石油天然气第六建设公司网站,杭州ui设计公司,门户网站建设推广什么是序列化?反序列化? 场景使用? 怎么实现?
今天我来带你扫扫盲, 关于什么是序列化?反序列化? 场景使用? 怎么实现??? 或许我们平时大概知道, 嗯,序列化,就是实现 Serializable 接口, 那再问你,怎么实现的, 或许你就有点懵逼,这篇, 让我们来 look 一 look 吧。
一…什么是序列化?反序列化? 场景使用? 怎么实现?
今天我来带你扫扫盲, 关于什么是序列化?反序列化? 场景使用? 怎么实现??? 或许我们平时大概知道, 嗯,序列化,就是实现 Serializable 接口, 那再问你,怎么实现的, 或许你就有点懵逼,这篇, 让我们来 look 一 look 吧。
一.什么是序列化?反序列化? 序列化指把堆内存中的 Java 对象数据通过某种方式把对象存储到磁盘文件中或者传递给其他网络节点在网络上传输。这个过程称为序列化。通俗来说就是将数据结构或对象转换成二进制数据流的过程 反序列化把磁盘文件中的对象数据或者把网络节点上的对象数据恢复成Java对象模型的过程。也就是将在序列化过程中所生成的二进制数据流转换成数据结构或者对象的过程 二. 为什么要序列化和反序列化什么场景使用? ①、在分布式系统中此时需要把对象在网络上传输就得把对象数据转换为二进制形式需要共享的数据的 JavaBean 对象都得做序列化。 ②、服务器钝化如果服务器发现某些对象好久没活动了那么服务器就会把这些内存中的对象持久化在本地磁盘文件中Java对象转换为二进制文件如果服务器发现某些对象需要活动时先去内存中寻找找不到再去磁盘文件中反序列化我们的对象数据恢复成 Java 对象。这样能节省服务器内存。 我们想一想, 当两个进程进行远程通信时可以相互发送各种类型的数据包括文本、图片、音频、视频等,这些如何实现的呢?
没错,这其中就用到了 Java序列化与反序列化了 ~~~ 这些数据都会以二进制序列的形式在网络上传送。
一句话概括就是 , 发送方 发送数据需要把这个Java对象转换为字节序列然后在网络上传送 ; 然后接收方需要从字节序列中恢复出Java对象。从而达到传送的目的~~
总的来说: 使用场景归纳如下:
1.把内存中的对象保存到一个文件中或者数据库中
2. 网络上传送对象
3.通过RMI传输对象RMI-Remote Method Invocation 远程方法调用小锦囊: RMI是什么? RMIRemote Method Invocation远程方法调用是bai用Java在JDK1.1中实现的它du大大增强了Java开发分布式应用zhi的能力。Java作为一种风靡一dao时的网络开发语言其巨大的威力就体现在它强大的开发分布式网络应用的能力上而RMI就是开发百分之百纯Java的网络分布式应用系统的核心解决方案之一。其实它可以被看作是RPC的Java版本。但是传统RPC并不能很好地应用于分布式对象系统。而Java RMI 则支持存储于不同地址空间的程序级对象之间彼此进行通信实现远程对象之间的无缝远程调用。 三. 序列化有什么作用?好处?
1.描述数据的传输格式这样可以方便自己组织数据传输格式以至于避免一些麻烦及错误
2.如果是跨平台的序列化则发送方序列化后接收方可以用任何其支持的平台反序列化成相应的版本比如 Java序列化后 用.net、phython等反序列化
3.利用序列化实现远程通信即在网络上传送对象的字节序列。
4.为了解决对象流读写操作时可能引发的问题(如果不进行序列化,可能会存在数据乱序的问题)
5.实现了数据的持久化通过序列化可以把数据永久地保存到硬盘上通常存放在文件里
6.序列化除了能够实现对象的持久化之外还能够用于对象的深度克隆四.如何实现 序列化和反序列化?
Java API提供了对序列化的支持
1、JDK类库中序列化和反序列化API
1java.io.ObjectOutputStream表示对象输出流
它的writeObject(Object obj)方法可以对参数指定的obj对象进行序列化把得到的字节序列写到一个目标输出流中
2java.io.ObjectInputStream表示对象输入流
它的readObject()方法源输入流中读取字节序列再把它们反序列化成为一个对象并将其返回序列化图示: 反序列化图示:
实现序列化的前提
必须实现了Serializable或Externalizable接口的类的对象才能被序列化否则抛出异常 实现代码
第一步创建一个 JavaBean 对象
package com.czxy.domain;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;/*** author 煌siritcast.cn* version 1.0**/
Table(name t_area)
Data
AllArgsConstructor
NoArgsConstructor
public class Area implements Serializable {Idprivate Integer id;private String name;
}第二步:在测试类使用 ObjectOutputStream 对象实现序列化 Testpublic void run1() throws Exception {Area a new Area(1, 煌sir6666);File file new File(E:\\file\\student.txt); //文件位置file.createNewFile(); //自动创建文件FileOutputStream fos new FileOutputStream(file);ObjectOutputStream oos new ObjectOutputStream(fos);oos.writeObject(a);oos.flush();oos.close();fos.close();}运行成功后, 在存储文件中,会有一长串乱码,这是二进制文件 当然, 我们不需要看懂, 只要电脑能识别就行了,嚯嚯~~~
第三步在测试类使用ObjectInputStream 对象实现反序列化 Testpublic void run2() throws Exception {File file new File(E:\\file\\student.txt); //文件位置FileInputStream fis new FileInputStream(file);ObjectInputStream ois new ObjectInputStream(fis);Area a (Area) ois.readObject();System.out.println(id: a.getId());System.out.println(aname: a.getName());//关闭ois.close();fis.close();}输出结果: 问题1: 如果我们某些数据不需要序列化,怎么办? 解决: 在字段面前加上 transient
Transient关键字的作用是控制变量的序列化在变量声明前加上该关键字可以阻止该变量被序列化到文件中在被反序列化后transient变量的值被设为初始值如int型的是0对象型的是 null。
transient表示瞬态的被transient关键字修饰的变量不再能被序列化一个静态变量不管是否被transient修饰均不能被序列化。 Idprivate Integer id; //序列化transient private String name; //不需要序列化
}运行结果如下: 问题2: 序列化版本问题在完成序列化操作后由于项目的升级或修改可能我们会对序列化对象进行修改比如增加某个字段那么我们在进行反序列化就会报错 解决
在 JavaBean 对象中增加一个 serialVersionUID 字段用来固定这个版本无论我们怎么修改版本都是一致的就能进行反序列化了
private static final long serialVersionUID 8656128222714547171L;五. 注意事项 1、序列化时只对对象的状态进行保存而不管对象的方法 2、当一个父类实现序列化子类自动实现序列化不需要显式实现Serializable接口 3、当一个对象的实例变量引用其他对象序列化该对象时也把引用对象进行序列化 4、并非所有的对象都可以序列化至于为什么不可以有很多原因了比如 安全方面的原因比如一个对象拥有privatepublic等field对于一个要传输的对象比如写到文件或者进行RMI传输等等在序列化进行传输的过程中这个对象的private等域是不受保护的 资源分配方面的原因比如socketthread类如果可以序列化进行传输或者保存也无法对他们进行重新的资源分配而且也是没有必要这样实现 5、声明为static和transient类型的成员数据不能被序列化。因为static代表类的状态transient代表对象的临时数据。 6、序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。为它赋予明确的值。显式地定义serialVersionUID有两种用途 在某些场合希望类的不同版本对序列化兼容因此需要确保类的不同版本具有相同的serialVersionUID 在某些场合不希望类的不同版本对序列化兼容因此需要确保类的不同版本具有不同的serialVersionUID。 7、Java有很多基础类已经实现了serializable接口比如String,Vector等。但是也有一些没有实现serializable接口的 8、如果一个对象的成员变量是一个对象那么这个对象的数据成员也会被保存这是能用序列化解决深拷贝的重要原因