序列化
Java 序列化技术可以使你将一个对象的状态写入一个Byte 流里,并且可以从其它地方把该Byte 流里的数据读出来,重新构造一个相同的对象。
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。
把Java对象转换为字节序列的过程称为对象的序列化。
把字节序列恢复为Java对象的过程称为对象的反序列化。
1、序列化的用途
利用对象的序列化可以保存应用程序的当前工作状态,下次再启动的时候将自动地恢复到上次执行的状态。
对象的序列化主要有两种用途:
(a) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
(b) 在网络上传送对象的字节序列。
2、序列化的实现
(1)JDK类库中的序列化API
java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自 Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式 。
(2)对象序列化与反序列化的过程
将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个 ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
对象序列化包括如下步骤:
(a)创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;
(b)通过对象输出流的writeObject()方法写对象。
对象反序列化的步骤如下:
(a)创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;
(b)通过对象输入流的readObject()方法读取对象。
下面让我们来看一个对应的例子,类的内容如下:
Java代码
- import java.io.*;
- import java.util.Date;
- public class ObjectSaver {
- public static void main(String[] args) throws Exception {
- ObjectOutputStream out = new ObjectOutputStream
- (new FileOutputStream("D:""objectFile.obj"));
- //序列化对象
- Customer customer = new Customer("阿蜜果", 24);
- out.writeObject("你好!");
- out.writeObject(new Date());
- out.writeObject(customer);
- out.writeInt(123); //写入基本类型数据
- out.close();
- //反序列化对象
- ObjectInputStream in = new ObjectInputStream
- (new FileInputStream("D:""objectFile.obj"));
- System.out.println("obj1=" + (String) in.readObject());
- System.out.println("obj2=" + (Date) in.readObject());
- Customer obj3 = (Customer) in.readObject();
- System.out.println("obj3=" + obj3);
- int obj4 = in.readInt();
- System.out.println("obj4=" + obj4);
- in.close();
- }
- }
- class Customer implements Serializable {
- private String name;
- private int age;
- public Customer(String name, int age) {
- this.name = name;
- this.age = age;
- }
- public String toString() {
- return "name=" + name + ", age=" + age;
- }
- }
- import java.io.*;
- import java.util.Date;
- public class ObjectSaver {
- public static void main(String[] args) throws Exception {
- ObjectOutputStream out = new ObjectOutputStream
- (new FileOutputStream("D:""objectFile.obj"));
- //序列化对象
- Customer customer = new Customer("阿蜜果", 24);
- out.writeObject("你好!");
- out.writeObject(new Date());
- out.writeObject(customer);
- out.writeInt(123); //写入基本类型数据
- out.close();
- //反序列化对象
- ObjectInputStream in = new ObjectInputStream
- (new FileInputStream("D:""objectFile.obj"));
- System.out.println("obj1=" + (String) in.readObject());
- System.out.println("obj2=" + (Date) in.readObject());
- Customer obj3 = (Customer) in.readObject();
- System.out.println("obj3=" + obj3);
- int obj4 = in.readInt();
- System.out.println("obj4=" + obj4);
- in.close();
- }
- }
- class Customer implements Serializable {
- private String name;
- private int age;
- public Customer(String name, int age) {
- this.name = name;
- this.age = age;
- }
- public String toString() {
- return "name=" + name + ", age=" + age;
- }
- }
输出结果如下:
Java代码
- obj1=你好!
- obj2=Sat Sep 26 22:02:21 CST 2010
- obj3=name=阿蜜果, age=24
- obj4=123
- obj1=你好!
- obj2=Sat Sep 26 22:02:21 CST 2010
- obj3=name=阿蜜果, age=24
- obj4=123
因此例比较简单,在此不再详述。
3、serialVersionUID作用:
序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。
有两种生成方式:
一个是默认的1L,比如:
Java代码
- private static final long serialVersionUID = 1L;
- private static final long serialVersionUID = 1L;
一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:
Java代码
- private static final long serialVersionUID = xxxxL;
- private static final long serialVersionUID = xxxxL;
二、克隆
有时想得到对象的一个复制品,该复制品的实体是原对象实体的克隆。复制品实体的变化不会引起原对象实体发生变化,这样的复制品称为原对象实体的克隆对象或简称克隆。
1、浅复制(浅克隆)
概念:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
方法:类implements Cloneable,然后重写clone()方法,在clone()方法中调用super.clone()即可,没有其他操作了
2、深复制(深克隆)
概念:被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍
方法:
(1)类implements Cloneable,然后重写clone()方法,在clone()方法中调用super.clone(),然后还要对引用型变量所指的对象进行克隆。
(2)序列化:将该对象写出到对象输出流,那么用对象输入流读回的对象就是原对象的一个深度克隆
相关推荐
克隆和序列化(Java )实例和源代码
Kryo - 针对Java的快速和高效对象图序列化框架
在学习编程的过程中,我觉得不止要获得课本的知识,更多的是通过学习技术知识提高解决问题的能力,这样我们才能走...这篇文章主要给大家介绍了Java中对象的序列化方式克隆,需要的朋友可以参考借鉴,下面来一起看看吧。
本篇文章是对序列化存取实现java对象深度克隆的方法进行了详细的分析介绍,需要的朋友参考下
ion-java, Java流解析器/序列化程序 一个Java实现的数据符号 。 设置这个库包含一个 git模块 ion-tests,它保存了 ion-java 测试单元使用的测试数据。克隆 ion-java 存储库并初始化它的ion-tests 模块的最简单方法是...
Kryo是用于Java的快速高效的二进制对象图序列化框架。 该项目的目标是高速,小尺寸和易于使用的API。 每当需要将对象持久保存到文件,数据库还是通过网络时,该项目都是有用的。 Kryo还可以执行自动的深层和浅层...
示例Bean.java 公共类ExampleBean { 私有 int id; 私人用户用户; 私人名单名单; 公共 int getId() { 返回ID; } 公共无效setId(int id){ 这个.id = id; } 公共用户 getUser() { 返回用户; } ...
java序列号反序列化工具类,支持深克隆。
主要介绍了Java利用序列化实现对象深度clone的方法,实例分析了java序列化及对象克隆的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
它包括一个低级字节库,序列化和反序列化编解码器(例如 ),各种加密功能和基元以及许多其他有用的实用程序。 Tuweni是为JDK 11或更高版本开发的。 制作说明 安装 。 与子模块一起克隆 git clone ...
java-ee-rxjava-kafka-avro 在Java EE 7应用程序中使用Avro作为事件序列化器/反序列化器和RxJava将Kafka用作事件源使用之前确保已安装并正在运行Kafka 0.8.2.1。如何使用它克隆存储库打开您的IDE并在您喜欢的Java EE...
实例057 序列化与对象克隆 84 实例058 深克隆效率的比较 87 第7章 面向对象进阶 89 实例059 经理与员工的差异 90 实例060 重写父类中的方法 92 实例061 计算几何图形的面积 93 实例062 简单的汽车销售商场 95 实例...
10 10序列化与对象克隆 10 11文件锁FileLock 10 12Process类中的流 10 13带进度条的输入流 习题 第11章Java网络的基本知识 11 1使用URL 11 2读取URL中的资源 11 3显示URL资源中的HTML文件 11 4处理超链接 11 5...
12.2.8 通过序列化进行深层复制 12.2.9 使克隆具有更大的深度 12.2.10 为什么有这个奇怪的设计 12.3 克隆的控制 12.3.1 副本构建器 12.4 只读类 12.4.1 创建只读类 12.4.2 “一成不变”的弊端 12.4.3 不变字串 ...
深拷贝:指的是拷贝一个对象时,不仅仅把对象的引用进行复制,还把该对象引用的值也一起拷贝。如果引用类型里面还包含很多引用类型,或者内层引用类型的类里面又包含多层...这时我们可以用序列化来实现对象的深拷贝。
12.2.8 通过序列化进行深层复制 12.2.9 使克隆具有更大的深度 12.2.10 为什么有这个奇怪的设计 12.3 克隆的控制 12.3.1 副本构建器 12.4 只读类 12.4.1 创建只读类 12.4.2 “一成不变”的弊端 12.4.3 不变字串 ...
12.2.8 通过序列化进行深层复制 12.2.9 使克隆具有更大的深度 12.2.10 为什么有这个奇怪的设计 12.3 克隆的控制 12.3.1 副本构建器 12.4 只读类 12.4.1 创建只读类 12.4.2 “一成不变”的弊端 12.4.3 不变字串 ...
031217_【第12章:JAVA IO】_对象序列化笔记.pdf 031218_〖第12章:JAVA IO〗_实例操作—单人信息管理程序笔记.pdf 031219_〖第12章:JAVA IO〗_实例操作:投票程序笔记.pdf 031301_【第13章:Java类集】_认识类集、...
58.什么是 java 序列化?什么情况下需要序列化? 59.动态代理是什么?有哪些应用? 60.怎么实现动态代理? 五、对象拷贝 61.为什么要使用克隆? 62.如何实现对象克隆? 63.深拷贝和浅拷贝区别是什么? 六、Java Web ...