Java 对象序列化和反序列化 (实现 Serializable 接口)

序列化和反序列化的概念

  把对象转换为字节序列的过程称为对象的序列化

    把字节序列恢复为对象的过程称为对象的反序列化

  对象的序列化主要有两种用途:
  1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
  2) 在网络上传送对象的字节序列。

 

JDK类库中的序列化API

  java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中
  java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回
  只有实现SerializableExternalizable接口的类的对象才能被序列化。Externalizable接口继承自 Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,

  而仅实现Serializable接口的类可以 采用默认的序列化方式 。

  对象序列化包括如下步骤: 

    1) 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;
  2) 通过对象输出流的writeObject()方法写对象。


  对象反序列化的步骤如下:

  1) 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;
  2) 通过对象输入流的readObject()方法读取对象。

示例:

 新建一个Car 类

 1 package com.oukele.redis2.entity;
 2 
 3 import java.io.Serializable;
 4 
 5 public class Car implements Serializable {
 6 
 7     /*
 8      * 编号
 9      */
10     private int id;
11     /*
12      * 车名
13      */
14     private String name;
15     /*
16      * 车速
17      */
18     private double speed;
19 
20     public Car(String name,double speed ){
21         this.name = name;
22         this.speed = speed;
23     }
24 
25     public Car(int id, String name, double speed) {
26         this.id = id;
27         this.name = name;
28         this.speed = speed;
29     }
30 
31     public int getId() {
32         return id;
33     }
34 
35     public void setId(int id) {
36         this.id = id;
37     }
38 
39     public String getName() {
40         return name;
41     }
42 
43     public void setName(String name) {
44         this.name = name;
45     }
46 
47     public double getSpeed() {
48         return speed;
49     }
50 
51     public void setSpeed(double speed) {
52         this.speed = speed;
53     }
54 
55     @Override
56     public String toString() {
57         return "Car{" +
58                 "id=" + id +
59                 ", name='" + name + '\'' +
60                 ", speed=" + speed +
61                 '}';
62     }
63 }

新建一个 SerializeUtil 类 (封装 序列化 和 反序列化 的方法,便于调用 )

 1 package com.oukele.redis2.util;
 2 
 3 import java.io.ByteArrayInputStream;
 4 import java.io.ByteArrayOutputStream;
 5 import java.io.ObjectInputStream;
 6 import java.io.ObjectOutputStream;
 7 
 8 public class SerializeUtil {
 9 
10     /*
11     * 序列化
12     * */
13     public static byte[] serialize(Object object){
14         //序列化流 (输出流) --> 表示向一个目标 写入数据
15         ObjectOutputStream objectOutputStream =null;
16         //字节数组输出流
17         ByteArrayOutputStream byteArrayOutputStream = null;
18         try{
19             //创建一个缓冲区
20             byteArrayOutputStream = new ByteArrayOutputStream();
21             //将 对象 序列化成 字节后  输入缓冲区中
22             objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
23             //序列化 对象
24             objectOutputStream.writeObject(object);
25             //得 到 序列化字节
26             byte[] bytes = byteArrayOutputStream.toByteArray();
27 
28             //清空输出流
29             objectOutputStream.flush();
30             //释放资源
31             objectOutputStream.close();
32 
33             return bytes;
34         }catch (Exception e){
35             System.out.println("出现异常:"+e.getMessage());
36         }
37         return null;
38     }
39 
40     /*
41     * 反序列化
42     * */
43 
44     public static  <T> T deserialize(byte[] bytes,Class<T> clazz){
45        //字节数组
46         ByteArrayInputStream byteArrayInputStream = null;
47         try{
48             //将 得到的序列化字节 丢进 缓冲区
49             byteArrayInputStream = new ByteArrayInputStream(bytes);
50             //反序列化流 (输入流)--> 表示着从 一个 源头 读取 数据 , (读取 缓冲区中 的字节)
51             ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
52             //反序化成 一个对象
53             return (T)objectInputStream.readObject();
54         }catch (Exception e){
55             System.out.println("出现异常:"+e.getMessage());
56         }
57         return null;
58     }
59 
60 
61 }

 

测试:

1         //序列化一个对象
2         byte[] serialize = SerializeUitl.serialize(new Car(2,"宝马",88.8));
3         //反序列化
4         Car deserialize = SerializeUitl.deserialize(serialize, Car.class);
5         System.out.println(deserialize);

测试结果:

示例源码地址: 

posted @ 2018-12-26 19:45  追梦滴小蜗牛  阅读(6141)  评论(0编辑  收藏  举报