1、什么是序列化和反序列化

  Serialization(序列化)是一种将对象以一连串的字节描述的过程;deserialization(反序列化)是一种将这些字节重建成一个对象的过程。

2、什么情况下需要序列化

  a)当你想把内存中的对象保存到一个文件 中或者数据库中的时候;

  b)当你想用套接字socket在网络上传送对象的时候;

  c)当你想通过RMI(Remote Method Invocation)传输对象的时候;

3、如何实现序列化

  将需要序列化的类实现Serializable接口就可以了,Serializable接口中没有任何方法,可以理解为一个标记,即表明这个类可以序列化。

4、序列化和反序列化例子

  如果我们想要序列化一个对象,首先要创建某些OutputStream(如FileOutputStreamByteArrayOutputStream等),然后将这些OutputStream封装在一个ObjectOutputStream中。这时候,只需要调用writeObject()方法就可以将对象序列化,并将其发送给OutputStream(记住:对象的序列化是基于字节的,不能使用Reader和Writer等基于字符的层次结构)。而反序列的过程(即将一个序列还原成为一个对象),需要将一个InputStream(如FileInputStreamByteArrayInputStream等)封装在ObjectInputStream内,然后调用readObject()即可。

 /**
* Description 序列化接口Serializable示例
* Date 2018-10-22
* @author Encore.M
*/
package com.meng.javalanguage.Serializable; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable; public class MyTest implements Serializable {
private static final long serialVersionUID = 1L;
private String name = "mengjia";
private int age = 24;
public static void main(String[] args) { // 以下代码实现序列化
try{
// 输出流保存的文件名为my.out
// ObjectOutputStream能把Object输出成Byte流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("my.out"));
MyTest myTest = new MyTest();
oos.writeObject(myTest);
oos.flush(); // 缓冲流
oos.close(); // 关闭流
}catch(FileNotFoundException e) { e.printStackTrace();
}catch(IOException e) { e.printStackTrace();
} deserialization(); // 调用下面的反序列化函数
} /**
* @description 反序列化,将字节流重建为对象
* @param 无
* @return 无
* @author Encore.M
* @date 2018-10-22
* @annotation 需捕获ClassNotFoundException和IOException异常或在函数定义时throws这两个异常
*/
public static void deserialization() { ObjectInputStream oin = null; // 局部变量必须要初始化
try{ oin = new ObjectInputStream(new FileInputStream("my.out"));
}catch(FileNotFoundException e1) { e1.printStackTrace();
}catch(IOException e1 ) { e1.printStackTrace();
} MyTest mts = null;
try{
mts = (MyTest)oin.readObject(); // 由Object对象向下转型为MyTest对象
}catch(ClassNotFoundException e) { e.printStackTrace();
}catch(IOException e) { e.printStackTrace();
} System.out.println("name = " + mts.name);
System.out.println("age = " + mts.age);
}
}

  序列化MyTest成功后会在此项目的工作空间生成一个my.out文件。而反序列化MyTest是读取my.out后生成一个MyTest对象。

5、serialVersionUID

  注意到上面程序中有一个serialVersionUID,实现了Serializable接口之后,Eclipse就会提示你增加一个serialVersionUID,虽然不加的话上述程序依然能够正常运行。

  序列化ID在Eclipse下提供了两种生成策略

  • 一个是固定的1L
  • 一个是随机生成的一个不重复的long类型数据(实际上是使用JDK工具,根据类名、接口名、成员方法及属性等来生成)

  上面程序中,输出对象和读入对象使用的是同一个MyTest类。

  如果是通过网络传输的话,当MyTest类的serialVersionUID不一致时,那么反序列化就不能正常进行。例如在客户端A中MyTest类的serialVersionUID=1L,而在客户端B中MyTest类的serialVersionUID=2L,那么就不能重构这个MyTest对象。视图重构则会报java.io.InvalidClassException异常,因为这两个类的版本不一致。

  如果没有特殊需求的话,使用默认的1L就可以,这样可以确保代码一致时反序列化成功。那么随机生成的序列化ID有什么用呢,有些时候,通过改变序列化ID可以用来限制某些用户的使用。

6、静态变量序列化

  串行化只能保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量,而且串行化保存的只是变量的值,对于变量的任何修饰符都不能保存。

  如果把MyTest类中的name定义为static类型的话,试图重构,就不能得到原来的值,只能得到null。说明对静态成员变量值是不保存的。这其实比较容易理解,序列化保存的是对象的状态,静态变量属于类的状态,因此,序列化并不保存静态变量。

7、transient关键字

  transient关键字的作用是阻止实例中那些用此关键字声明的变量的持久化;当对象被反序列化时(从源码读取字节序列进行重构),这样的实例变量值不会被恢复。

  当某些变量不想被序列化,同时又不适合使用static关键字声明时,可以用transient关键字来声明该变量。在被反序列化后,transient变量的值被设为初始值,如int型的默认是0,对象型的是null。

  注:对于某些类型的属性,其状态是瞬时的,这样的属性是无法保存其状态的。例如一个线程属性或是需要访问IO、本地资源、网络资源等的属性,对于这些字段,我们必须用transient关键字标明,否则编译器将报错

8、序列化中的继承问题

  1)当一个父类实现序列化,子类自动实现序列化,不需要显示实现Serializable接口。

  2)一个子类实现了Serializable接口,它的父类都没有实现Serializable接口,要想将父类对象也序列化,就需要让父类也实现Serializable接口。

  第二种情况中,如果父类不实现Serializable接口的话,就需要有默认的无参构造函数。在父类没有实现Serializable接口时,虚拟机是不会序列化父对象的,而一个Java对象的构造必须先有父对象,才有子对象,反序列化也不例外。所以反序列化时,为了构造父对象,只能调用父类的无参构造函数作为默认的父对象。因此当我们取父对象的变量值时,它的值是调用父类无参构造函数后的值。如果你考虑到这种序列化的情况,在父类无参构造函数中对变量进行初始化,否则,父类变量值都是默认声明的值,如int型的默认是0,string型的默认是null

9、总结

  序列化给我们提供了一种技术,用户保存对象的变量,以便于 传输。虽然也可以使用别的一些方法实现同样的功能,但是java给我们提供的方法使用起来是非常方便的。

Java序列化Serializable的更多相关文章

  1. Java 序列化Serializable详解

    Java 序列化Serializable详解(附详细例子) Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化Serialization(序列化)是一种将对象以一连 ...

  2. Java 序列化Serializable详解(附详细例子)

    Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization ...

  3. Java 序列化Serializable具体解释(附具体样例)

    Java 序列化Serializable具体解释(附具体样例) 1.什么是序列化和反序列化 Serialization(序列化)是一种将对象以一连串的字节描写叙述的过程:反序列化deserializa ...

  4. java 序列化Serializable 详解

    Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是 ...

  5. Java 序列化Serializable详解(附详细例子)

    Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是 ...

  6. java:序列化Serializable 接口

    java:序列化Serializable 接口 public class SerializePerson implements Serializable { private String name; ...

  7. Java 序列化Serializable接口

    1 什么是序列化和反序列化 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程. 2  什么情况下需要 ...

  8. Java序列化Serializable和Externalizable

    纸上得来终觉浅,绝知此事要躬行  --陆游       问渠那得清如许,为有源头活水来  --朱熹 什么是Java序列化?为什么出现Java序列化?怎样实现Java序列化? 一.什么是Java序列化 ...

  9. Java 序列化Serializable

    a)当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口: b)当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化: c) static,trans ...

随机推荐

  1. myeclipse使用步骤总结

    1.安装和破解:http://www.cnblogs.com/haimishasha/p/5203069.html 2.修改编码方式:http://www.cnblogs.com/haimishash ...

  2. 5.Hystrix-服务降级

    所谓降级,就是当某个服务出现异常之后,服务器将不再被调用,此时服务端可以自己准备一个本地的fallback回调,返回一个缺省值. 这样做,虽然服务水平下降,但好歹可用,比直接挂掉要强,当然这也要看适合 ...

  3. DirectX11 With Windows SDK--03 索引缓冲区、常量缓冲区

    前言 一个立方体有8个顶点,然而绘制一个立方体需要画12个三角形,如果按照前面的方法绘制的话,则需要提供36个顶点,而且这里面的顶点数据会重复4次甚至5次.这样的绘制方法会占用大量的内存空间. 接下来 ...

  4. 解决 git push Failed to connect to 127.0.0.1 port 8-87: 拒绝连接

    今天在本地使用nsq 测试的时候总是提示端口被占用 通过查看环境变量确实存在该代理 如何解决 使用netstat 命令查看端口被占用情况 根据经常ID号查看是哪一个进程正在被占用 如何还是不行,则在[ ...

  5. Win10升级.NET Framework 3.5或2.0遇到错误0x800f081f怎么办

    为了让win10系统更好地运行游戏,很多玩家都会在电脑中安装.NET Framework 3.5或.NET Framework 2.0.不过,部分用户在更新升级.NET Framework 3.5和2 ...

  6. C#下RSA算法的实现(适用于支付宝和易宝支付)

    RSA算法代码: using System; using System.Collections.Generic; using System.Text; using System.IO; using S ...

  7. U盘中毒后变为快捷方式的解决方法

    今天神奇地发现,如果U盘中毒后,变为快捷方式,那么你可以有三种解决方法: (1)在网上下一个脚本程序,将文件恢复: (2)使用U盘查杀的工具,一般的工具应该有U盘文件恢复这一项,比如金山的杀毒软件: ...

  8. Groovy 设计模式 -- null对象模式

    Null Object Pattern http://groovy-lang.org/design-patterns.html#_loan_my_resource_pattern 对于一些场景获得的对 ...

  9. 【51nod 1191】消灭兔子

    Description 有N只兔子,每只有一个血量B[i],需要用箭杀死免子.有M种不同类型的箭可以选择,每种箭对兔子的伤害值分别为D[i],价格为P[i](1 <= i <= M).假设 ...

  10. Eclipse下生成/编辑Java类图或时序图(UML)[转载]

    一 引用文章 1.[eclipse下生成Java类图和时序图,生成UML图(更完整版)](https://blog.csdn.net/guomainet309/article/details/5302 ...