实现对象的序列化和反序列化

一、什么是对象的序列化和反序列化

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

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

 

二、为什么要实现对象的序列化

1.把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中

2.在网络上传输数据,将对象以字节序列地方式进行传送

当需要存储大量对象(数十万个对象时,内存可能无法存储),这时就需要把对象进行序列化存储到硬盘中,等需要用的时候,再将硬盘中的对象还原到内存中进行使用。

当两个进程需要远程通信时,彼此可以发送各种类型的数据。虽然我们表面上看到的数据千奇百怪,表情、文字、符号等等,其实它们在网络上都是以二进制序列的形式进行传输的。发送方需要把这个java对象转换成字节序列,然后将二进制序列发送到网络上;此时,接受方收到消息,然后将二进制序列恢复为java对象。

 

三、如何实现序列化

3.1、使用JDK自带的API

java.io.ObjectOutputStream对象输出流,调用writeObject(Object obj)方法可以将obj对象进行序列化,把得到的字节序列写到一个目标输出流中。下面是以文件输出流为例子。

java.io.ObjectInputStream对象输入流,调用readObject(Object obj)方法从一个源输入流中读取字节序列,再把字节序列反序列为一个对象,并将对象返回。

实现了序列化接口的实体类:

public class Student implements Serializable{
    private String id;
    private String name;
    private String sex;
    private String grade;

    //无参构造
    public Student() {
    }

    //带参构造
    public Student(String id, String name, String sex, String grade) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.grade = grade;
    }

    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getGrade() {
        return grade;
    }

    public void setGrade(String grade) {
        this.grade = grade;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", grade='" + grade + '\'' +
                '}';
    }
}

 

实现序列化和反序列化的工具类:

public class ObjSerializeAndDeserialize {

    private static String filePath= Environment.getExternalStorageDirectory()+File.separator+"student.txt";

    public static void SerializeStudent(Student student) throws FileNotFoundException,IOException{

        //ObjectOutputStream对象输出流,将Student对象存储到E盘的student.txt中,从而实现序列化和存储
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(new File(filePath)));

        //将对象进行写入
        oos.writeObject(student);
        oos.close();
    }

    public static Student DeserializeStudent() throws ClassNotFoundException, IOException{
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream(filePath));

        Student student=(Student) ois.readObject();
        ois.close();

        return student;
    }
}

运行结果:

序列化结果:

 

反序列化结果:

 

序列化Student成功后在存储目录中生成了一个student.txt文件,反序列化对象则是读取student.txt内容,并返回一个Student对象

 

 

3.2、使用第三方工具Gson

这个就比较简单了,直接使用Gson工具中的toJson(Object obj)方法,就可以将对象转化成jsonString字符串。

 

反序列化直接调用fromJson(String json),就可以得到之前的对象了。

 

四、serialVersionUID的作用

凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量。在完成序列化后,java编译器会自动给这个class进行一个摘要算法,类似于指纹算法,只要文件发生任何改变,得到的UID就会不一样。那么可能由于我们对序列化对象的修改,比如增加某个属性,就会导致反序列化报错。

要解决这样的问题,serialVersionUID 就派上用场了,只要在javaBean对象中增加一个serialVersionUID 字段,用来标识这个类,而不是由编译器自动生成,这样当我们修改这个类时,反序列化就不会报错了。

private static final long serialVersionUID = 235412822564145941515L;

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值