序列化与反序列化

什么是序列化?

序列化就是将内存中的对象转换成字节序列后进行传输到指定的文件,也可以在网络之间进行传输

如何实现序列化?

  • 我们实现序列化,需要实现一个接口“Serializable
  • 需要使用到ObjectOutputStream类

案例:实现对象的序列化

1.创建一个简单类

import java.io.Serializable;

public class Emp implements Serializable {
    private transient Integer empno;
    private String ename;
    private String job;
    private Double sal;
    private Integer mgr;//领导编号
    private  Integer deptno;//部门编号

    public Emp(Integer empno, String ename, String job, Double sal, Integer mgr, Integer deptno) {
        this.empno = empno;
        this.ename = ename;
        this.job = job;
        this.sal = sal;
        this.mgr = mgr;
        this.deptno = deptno;
    }

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEname() {
        return ename;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public Double getSal() {
        return sal;
    }

    public void setSal(Double sal) {
        this.sal = sal;
    }

    public Integer getMgr() {
        return mgr;
    }

    public void setMgr(Integer mgr) {
        this.mgr = mgr;
    }

    public Integer getDeptno() {
        return deptno;
    }

    public void setDeptno(Integer deptno) {
        this.deptno = deptno;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "empno=" + empno +
                ", ename='" + ename + '\'' +
                ", job='" + job + '\'' +
                ", sal=" + sal +
                ", mgr=" + mgr +
                ", deptno=" + deptno +
                '}';
    }
}

2、实现序列化

  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.ObjectOutputStream;
  import java.io.OutputStream;
  
  public class Demo {
      public static void main(String[] args) throws Exception{
          //创建一个File类对象
          File f = new File("D:"+File.separator+"java"+File.separator+"demo"+File.separator+"test.txt");
          //创建一个Emp对象
         Emp emp = new Emp(1001,"Jacob","Java",10000.0,1009,10);
         ser(f,emp);
      }
      //实现序列化的方法
      //f目标文件
      //o 需要序列化的对象
      public static void ser(File f,Object o)throws Exception{
          //判断目录是否存在
          if (!f.getParentFile().exists()){
              f.getParentFile().mkdirs();
          }
          //判断文件是否存在
          if (!f.exists()){
              f.createNewFile();
          }
          //创建一个字节输出流对象
          OutputStream ops=new FileOutputStream(f);
          //创建一个实现序列化的对象
          ObjectOutputStream oos=new ObjectOutputStream(ops);
          //实现序列化
          oos.writeObject(o);
          oos.close();
          ops.close();
      }
  }

结果:

 

 

为什么要序列化?以下是我摘抄别人优秀博客的

举个例子来说:假如我有两个类,分别是A和B,B类中含有一个指向A类对象的引用,

现在我们对两个类进行实例化{ A a = new A(); B b = new B(); }。这时在内存中实际上分配

了两个空间,一个存储对象a,一个存储对象b。接下来我们想将它们写入到磁盘的一个文件

中去,就在写入文件时出现了问题!因为对象b包含对对象a的引用,所以系统会自动的将a

的数据复制一份到b中,这样的话当我们从文件中恢复对象时(也就是重新加载到内存中)时,

内存分配了三个空间,而对象a同时在内存中存在两份,想一想后果吧,如果我想修改对象a

的数据的话,那不是还要搜索它的每一份拷贝来达到对象数据的一致性,这不是我们所希望的!

所以序列化解决的方案就是

1.保存到磁盘的所有对象都获得一个序列号(1, 2, 3等等)

2.当要保存一个对象时,先检查该对象是否被保存了

3.如果以前保存过,只需写入"与已经保存的具有序列号x的对象相同"的标记,否则,保存该对象

Java对象序列化后可以很方便的存储或者在网络中传输。

 如何对某些数据字段不序列化?

在序列化的过程中,有些数据字段我们不想将其序列化,对于此类字段我们只需要在定义

时给它加上transient关键字即可,对于transient字段序列化机制会跳过不会将其写入文件,当然

也不可被恢复

什么是反序列化?

和序列化相反,也就是将字节(反序列化)恢复为内存中的对象

实现反序列化

public class Demo {
    public static void main(String[] args) throws Exception{
        //创建一个File类对象
        File f = new File("D:"+File.separator+"java"+File.separator+"demo"+File.separator+"test.txt");
        //创建一个Emp对象
       Emp emp = new Emp(1001,"Jacob","Java",10000.0,1009,10);
       //调用反序列化方法
        dser(f);
    }
    public static void dser(File f) throws Exception{
        //创建一个字节输入流
        InputStream in=new FileInputStream(f);
        //创建一个实现反序列化的对象
        ObjectInputStream input=new ObjectInputStream(in);
        //实现反序列化
        Object obj=input.readObject();
        System.out.println(obj);
        //关闭
        input.close();
        in.close();
    }
}

 

posted @ 2022-04-30 10:59  卷心菜-小白  阅读(713)  评论(0)    收藏  举报