栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

序列化与反序列化

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

序列化与反序列化

文章目录
  • 1.概念
  • 2.序列化方法
    • 为什么要实现Serializable接口?
  • 3.反序列化方法
  • 4.多个对象的序列化与反序列化
  • 5.transient关键字
  • 6.关于序列化版本号

1.概念

序列化(Serialize):将Java对象存储到文件中。将Java对象的状态保存下来的过程。(将对象变为二进制比特流(字节)的过程。)序列化需要使用到的类:ObjectOutputStream(写)

反序列化(DeSerialize):将硬盘上的数据重新恢复到内存当中,恢复成Java对象。(将字节恢复成对象的过程。)反序列化需要使用到的类:ObjectInputStream(读)

2.序列化方法 为什么要实现Serializable接口?

需要对被序列化的对象的类实现Serializable接口,否则会出现异常:java.io.NotSerializableException。就是有一个Student类要对Student类的对象stu实现序列化,那么Student类就要实现Serializable接口。

通过源代码发现Serializable接口是一个标志接口,即接口中没有方法和属性(什么代码都没有)。Java虚拟机看到erializable标志会对实现了这个接口的类自动生成一个序列化版本号。序列化版本号是使用Java虚拟机默认提供的,也可自己设置。序列化版本号具体介绍见6

Java中有两种接口:普通接口、标志接口。标志接口起到标识的作用,标志接口是给Java虚拟机参考的。Java虚拟机看到这个标志会对实现了这个接口的类进行一些特殊的操作。

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class SerializeDemo {
    public static void main(String[] args) throws Exception{
        //创建对象
        Student s=new Student(11,"qwe");
        //序列化
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("students") );
        //"students"这里面存放的是序列化后的文件的存放发位置
        //序列化对象
        oos.writeObject(s);
        //刷新
        oos.flush();
        //关闭
        oos.close();
    }
}
public class Student implements Serializable {//标志性接口
    private int id;
    private String name;
    public Student(){ }
    public Student(int id, String name) {
        this.id = id;
        this.name = name;
    }
    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;
    }
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + ''' +
                '}';
    }
}

序列化结果为

3.反序列化方法
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("students"));
        //反序列化,读
        Object object = ois.readObject();
        System.out.println(object);

4.多个对象的序列化与反序列化

将对象放到集合中序列化集合

public class SerializeDemo {
    public static void main(String[] args) throws Exception{
        List list=new ArrayList<>();
        //创建对象
        Student s=new Student(11,"qwe");
        list.add(s);
        list.add(new Student(12,"we"));
        list.add(new Student(13,"wr"));
        //序列化
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("list") );
        //序列化集合,该集合中其他的对象
        oos.writeObject(list);
        //刷新
        oos.flush();
        //关闭
        oos.close();

        ObjectInputStream ois=new ObjectInputStream(new FileInputStream("list"));
        //反序列化,读
        
        List l=(List)ois.readObject();
        for (Student c:l
             ) {
            System.out.println(c);
        }
        ois.close();
    }
}


5.transient关键字

transient是游离的意思,表示修饰的成员变量不参与序列化。

将4当中的Student类的id属性用transient关键字修饰,代码执行的结果为

private transient int id;
private String name;

Student{id=0, name=‘qwe’}
Student{id=0, name=‘we’}
Student{id=0, name=‘wr’}

6.关于序列化版本号

Java语言中是采用什么机制来区分类的?

首先通过类名进行对比,类名不一样不为同一个类,其次如果类名一样,依靠序列化版本号来区分类(即两个类的类名都为com.serialize.Student,此时就要依靠序列化版本号来区分)。即序列化版本号的作用是来区分类的

代码编写后,过了很长时间要对Student类的源代码进行改动,将改动的代码重新编译后,就生成了新的字节码文件。并且当class文件再次运行时,Java虚拟机生成的序列化版本号也会发生变化。当用同样的代码再次进行反序列化(没有再次进行序列化)时会产生异常(java.io.InvalidClassException: com.serialize.Student; local class incompatible: stream classdesc serialVersionUID = -2426745935832763388, local class serialVersionUID = -366168221349123625),即不能进行反序列化。

建议:凡是一个类实现了Serializable接口(标志接口),建议给该类一个固定不变的序列化版本号(手动写出来,不自动生成)即在实现标志接口的类中添加:private static final long serialVersionUID =此处写自己设置的版本号L;

自动生成的序列化版本号的缺点:代码写好后不能再次进行修改类体。

Idea自动生成序列化版本号:

File–>Setting–>Editor–>Inspections–>搜索Serializable—>选择下面图片中的打勾—>Apply–>ok

选择实现标志接口的类的类名–>Alt+Enter–>选择Add ‘serialVersionUID’ field 即可生成序列化版本号

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/842883.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号