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

序列化和反序列化的概念

把对象转换为字节序列的过程称为对象的序列化。
把字节序列恢复为对象的过程称为对象的反序列化。
对象的序列化主要有两种用途:
  • 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
  • 在网络上传送对象的字节序列。

JDK类库中的序列化API

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

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

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

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

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

实体类

package com.oukele.redis2.entity;

import java.io.Serializable;

public class Car implements Serializable {

    /*
     * 编号
     */
    private int id;
    /*
     * 车名
     */
    private String name;
    /*
     * 车速
     */
    private double speed;

    public Car(String name,double speed ){
        this.name = name;
        this.speed = speed;
    }

    public Car(int id, String name, double speed) {
        this.id = id;
        this.name = name;
        this.speed = speed;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getSpeed() {
        return speed;
    }

    public void setSpeed(double speed) {
        this.speed = speed;
    }

    @Override
    public String toString() {
        return "Car{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", speed=" + speed +
                '}';
    }
}

SerializeUtil 类

package com.oukele.redis2.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SerializeUtil {

    /*
    * 序列化
    * */
    public static byte[] serialize(Object object){
        //序列化流 (输出流) --> 表示向一个目标 写入数据
        ObjectOutputStream objectOutputStream =null;
        //字节数组输出流
        ByteArrayOutputStream byteArrayOutputStream = null;
        try{
            //创建一个缓冲区
            byteArrayOutputStream = new ByteArrayOutputStream();
            //将 对象 序列化成 字节后  输入缓冲区中
            objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            //序列化 对象
            objectOutputStream.writeObject(object);
            //得 到 序列化字节
            byte[] bytes = byteArrayOutputStream.toByteArray();

            //清空输出流
            objectOutputStream.flush();
            //释放资源
            objectOutputStream.close();

            return bytes;
        }catch (Exception e){
            System.out.println("出现异常:"+e.getMessage());
        }
        return null;
    }

    /*
    * 反序列化
    * */

    public static  <T> T deserialize(byte[] bytes,Class<T> clazz){
       //字节数组
        ByteArrayInputStream byteArrayInputStream = null;
        try{
            //将 得到的序列化字节 丢进 缓冲区
            byteArrayInputStream = new ByteArrayInputStream(bytes);
            //反序列化流 (输入流)--> 表示着从 一个 源头 读取 数据 , (读取 缓冲区中 的字节)
            ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
            //反序化成 一个对象
            return (T)objectInputStream.readObject();
        }catch (Exception e){
            System.out.println("出现异常:"+e.getMessage());
        }
        return null;
    }
}

测试:

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);

猜你喜欢

转载自blog.csdn.net/weixin_43831653/article/details/85283571