一、定义

  序列化:将对象编码成字节流,并从字节流编码中重新构建的对象(将对象写入到IO流中)。换一种说法就是,序列化是用来处理对象流的一种机制,对象流就是将对象的内容进来流化(即将对象转化成二进制)。然后可以对流化的对象进行读写操作或者将其传输于网络之间。

  反序列化:将字节流重建成对象称之为反序列化(从IO流中恢复对象)。

 

二、什么时候需要实现序列化?为什么要实现序列化?

  什么时候:  

  对象序列化可以实现分布式对象(是在面向对象技术的基础上发展起来的,它要解决的主要问题是位于不同进程中的对象之间的调用问题。),RMI(Remote Method Invocation,远程方法调用)要利用对象序列化运行远程主机上的服务,就像在本机上运行对象时一样。

 

  为什么:

  (1)首先,序列化就是对实例对象的状态(状态 对象属性而不包括对象方法)进行通用编码并保存(例如:客户端可以调用服务器时,传递的参数是一个 Java 对象,比如叫 cat。服务器并没有那么智能,它并不会知道你传递的是一个 Java 对象,而不是其他类型的数据,它识别不了 Java 对象。Java 对象本质上是 class 字节码,服务器并不能根据这个字节码识别出该 Java 对象。所以,要提供一个公共的格式,不仅 Windows 能识别,你的服务器也能识别的公共的格式。将 Java 对象转换成公共的格式叫做序列化,将公共的格式转换成对象叫做反序列化。),以保证对象的完整性和可传递性。简单来说,序列化,就是为了在不同时间或不同平台的JVM之间共享实例对象。更通俗的解释,当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。


 

  (2)客户端访问了某个能开启会话功能的资源, web服务器就会创建一个与该客户端对应的HttpSession对象,每个HttpSession对象都要占用一定的内存空间。如果在某一时间段内访问站点的用户很多,web服务器内存中就会积累大量的HttpSession对象,消耗大量的服务器内存,即使用户已经离开或者关闭了浏览器,web服务器仍要保留与之对应的HttpSession对象,在他们超时之前,一直占用web服务器内存资源。

  web服务器通常将那些暂时不活动但未超时的HttpSession对象转移到文件系统或数据库中保存,服务器要使用他们时再将他们从文件系统或数据库中装载入内存,这种技术称为Session的持久化。将HttpSession对象保存到文件系统或数据库中,需要采用序列化的方式将HttpSession对象中的每个属性对象保存到文件系统或数据库中;将HttpSession对象从文件系统或数据库中装载入内存时,需要采用反序列化的方式,恢复HttpSession对象中的每个属性对象。


 

  (3)假如我有两个类,分别是A和B,B类中含有一个指向A类对象的引用,现在我们对两个类进行实例化{ A a = new A(); B b = new B(); }。这时在内存中实际上分配了两个空间,一个存储对象a,一个存储对象b。接下来我们想将它们写入到磁盘的一个文件中去,就在写入文件时出现了问题!因为对象b包含对对象a的引用,所以系统会自动的将a的数据复制一份到b中,这样的话当我们从文件中恢复对象时(也就是重新加载到内存中)时,内存分配了三个空间,而对象a同时在内存中存在两份。如果我想修改对象a的数据的话,那不是还要搜索它的每一份拷贝来达到对象数据的一致性,这不是我们所希望的!

 

三、如何实现序列化

  (1)实现serializable接口。(该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的。)

  (2)然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象

  (3)使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。

 

  例子

 创建一个可序列化的person类,继承了serializable之后,该类的属性皆可被序列化。

 1 import java.io.Serializable;
 2 
 3 public class Person implements Serializable {
 4    
 5     private String name=null;
 6     private Integer age=null;
 7     private Gender gender=null;
 8     
 9     public Person(){
10         System.out.println("non-arg constructor");
11     }
12     
13     public Person(String name,Integer age,Gender gender){
14         System.out.println("arg constructor");
15         this.name=name;
16         this.age=age;
17         this.gender=gender;
18     }
19     
20     public String getName(){
21         return name;
22     }
23     
24     public Integer getAge(){
25         return age;
26     }
27     
28     public Gender getGender(){
29         return gender;
30     }
31     
32     public void setName(String name){
33         this.name=name;
34     }
35     
36     public void setAge(Integer age){
37         this.age=age;
38     }
39     
40     public void setGender(Gender gender){
41         this.gender=gender;
42     }
43     
44     public String toString(){
45         return "["+name+",age "+age+",gender "+gender+"]";
46     }
47 }
View Code

对这个类进行运用,将name和age序列化(也就是把这2个对象转为二进制)

 1 import java.io.*;
 2 
 3 // 序列化是将对象状态转换为可保持或传输的格式的过程。
 4 // 说明白点就是你可以用对象输出流输出到文件。
 5 public class SerializibleTest {
 6     public static void main(String args[]) throws Exception{
 7         
 8         // 序列化后生成指定文件
 9         
10         /** File.seperator:文件路径分隔符
11          *    File file=new File("D:" + File.seperator + "person.out");
12          */
13         File file=new File("person.out");
14         
15         // 装饰流
16         ObjectOutputStream out = null;
17         out = new ObjectOutputStream(new FileOutputStream(file));
18         
19         // 实例化类
20         Person person = new Person("Jack",20,Gender.MALE);
21         
22         // 类对象序列化,writeObject方法进行输出保存
23         out.writeObject(person);
24         out.close();
25         
26        /** 
27         ObjectInputStream oin = null;
28         oin = new ObjectInputStream(new FileInputStream(file));
29         
30         Object newPerson = oin.readObject();
31         oin.close();
32         
33         System.out.println(newPerson);
34         */
35     }
36 }
posted on 2020-04-14 22:56  小潘同学  阅读(175)  评论(0)    收藏  举报
-->