Java基础——序列化与反序列化

定义:

  1. 序列化
    将内存中的对象写入到硬盘文件中
  2. 反序列化
    将硬盘文件中的对象数据读入到内存中

实现:

  1. 要操作的类一定要实现 Serializable 接口,类中所引用的类型的类也要实现 Serializable 接口,以此类推。Serialable 接口对 JVM 起到标识作用,实现类无需重写方法。只有实现了 Serializable 接口的类所产生的对象才能被序列化与反序列化
  2. 对象输出流 ObjectOutputStream 起到序列化的作用,对象输入流 ObjectInputStream 起到反序列化的作用

序列化版本号

序列化版本号是类的标识,将序列化好的对象与它对应的类联系起来。类的自定义序列化版本号是静态常量。

public class Roster implements Serializable {
    //自定义序列化版本号
    private static final long serialVersionUID = 1L;
}

序列化好的对象可以通过序列化版本号找到它所对应的类。
如果类没有自定义序列化版本号,JVM 将分配版本号,对类做出更改后,类又被分配新的版本号,这时,原来的类的已经序列化好的对象就无法反序列化了,因为原来的版本号没有所对应的类了。
对于有自定义序列化版本号的类,对类做出修改后,原来就序列化好的对象能够反序列化,缺的属性增加上,赋默认值;多出来的属性舍弃。为了数据的正常存储,序列化版本号应当是自定义的全球独一无二的。

实例:

在第一次序列化前,不要执行反序列化,因为空文件无法被反序列化
第一次运行:

import java.io.*;
import java.util.Scanner;

//测试类
public class Test {
    //main方法
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        Person p1 = new Person(1001,"张三");
//第一次运行程序时不执行反序列化,因为空文件无法被反序列化
//        //反序列化
//        System.out.println("从硬盘文件读入数据");
//        Deserialization deserialization = new Deserialization();
//        p1 = (Person)deserialization.deserialize();
        //输出信息
        System.out.println(p1);
        System.out.println("请输入新名字");
        String name = in.next();
        p1.setName(name);
        System.out.println("修改成功");
        System.out.println(p1);
        //序列化
        Serialization serialization = new Serialization(p1);
        System.out.println("保存成功");
        System.out.println("程序退出");
        System.exit(1);
    }
}

//序列化类
class Serialization {
    public Serialization(Object object) {
        //创建对象输出流
        ObjectOutputStream oos = null ;
        //操作流
        try {
            //序列化,把内存中的对象写入到硬盘文件 Roster.dat 中
            oos = new ObjectOutputStream(new FileOutputStream("D:\\PersonDate\\Roster.dat"));
            oos.writeObject(object);
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(oos != null) {
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

//反序列化类
class Deserialization {
    public Deserialization() {  }
    public Object deserialize() {
        Object object=null;
        //创建对象输入流
        ObjectInputStream ois = null;
        //操作流
        try {
            //反序列化,把对象从硬盘读出到内存中
            ois = new ObjectInputStream(new FileInputStream("D:\\PersonDate\\Roster.dat"));
            object = (Object) ois.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (ois != null) {
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return object;
    }
}

//人类
class Person implements Serializable {
    //序列化版本号
    private static final long serialVersionUID = 20220611L;
    //属性
    private int Id;
    private String name;
    //构造方法
    public Person(int Id,String name) {
        this.Id = Id;
        this.name = name;
    }
    //修改方法
    public void setName(String name) {
        this.name = name;
    }
    //输出信息方法
    @Override
    public String toString() {
        return "Person{" +
                "Id=" + Id +
                ", name='" + name + '\'' +
                '}';
    }
}

/*运行结果:
Person{Id=1001, name='张三'}
请输入新名字
李四
修改成功
Person{Id=1001, name='李四'}
保存成功
程序退出
*/

第二次运行:

//代码同第一次运行,但不将反序列化语句注释掉,使得反序列化功能执行
--------代码同上--------

/*运行结果:
从硬盘读入数据
Person{Id=1001, name='李四'}
请输入新名字
*/

总结

如示例代码所示,使用序列化与反序列化可以实现数据的更新与保存。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值