[Java进阶] 序列化和反序列化的使用

🍑什么是序列化

当我们执行程序需要多个对象数据的时候, 每次执行程序都有重新创建赋值, 很消耗资源, 可以将对象的完整信息保存在文件中, 之后可以使用反序列化从文件中将对象读取出来

序列化流

ObjectOutputStream(OutputStream os): 负责将对象序列化, 并不具备写文件的功能

反序列化流

ObjectInputStream(InputStream is) : 负责将对象反序列化, 并不具备读文件的功能

🍑单个对象的序列化和反序列化

序列化:

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

public class SeriableDemo {
    public static void main(String[] args) throws Exception{
        //person类要实现Serializable接口
        Person person = new Person("马思纯",18);

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("io\\序列化.txt"));
        oos.writeObject(person);
        oos.close();
    }
}

反序列化:

import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class SerializableDemo2 {
    public static void main(String[] args) throws Exception {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("io\\序列化.txt")));

         Person p = (Person) ois.readObject();

        System.out.println(p);
    }
}

🍑多个对象的序列化和反序列化

不建议将对象一个一个序列化, 反序列化读取时没有末尾的结束标记, 一旦读取到末尾就报异常, 因此不能使用循环读取, 导致操作不方便

建议将对象存入ArrayList集合中, 序列化和反序列化只针对一个数组进行操作

序列化:

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collections;

public class SeriableDemo3 {
    public static void main(String[] args) throws Exception{
        //person类要实现Serializable接口
        Person person1 = new Person("马思纯",18);
        Person person2 = new Person("倪妮",18);
        Person person3 = new Person("杨幂",18);

        ArrayList<Person> personList = new ArrayList<>();
        Collections.addAll(personList,person1,person2,person3);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("io\\序列化.txt"));
        oos.writeObject(personList);
        oos.close();
    }
}

反序列化:

import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;

public class SerializableDemo2 {
    public static void main(String[] args) throws Exception {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("io\\序列化.txt")));

        ArrayList<Person> list = (ArrayList<Person>) ois.readObject();
        list.forEach(System.out::println);
    }
}

🍑序列化的serialVersionUID标记

序列化后 反序列化前对类做了内容上的更改, 会报错: 无效类异常

serialVersionUID是实现序列化的类通过组成部分, 计算出long类型身份id(隐式).

一旦更改组成部分,相当于给类更换了新的UID, 反序列化就不能通过序列化时的serialVersionUID找到类 , 文件出来的字节序列就不能反序列化成类对象

解决方式:     

保证类的serialVersionUID值不更改

类中不定义会系统默认生成serialVersionUID值, 如果在类中自己显示生成, 就使用自己定义的值保存

1. 自己定义private static final serialVersionUID = 123456L;

2. 使用IDEA快捷生成一个UID

🍑使用瞬态关键字脱敏

某个字段的值不想被序列化到文件中,使用瞬态关键字transient

eg: 对象("张三",18) 对年龄使用瞬态关键字, 真正序列到文件中的只有"张三". 反序列化回来的时候, 年龄字段是默认值

🍑总结

1. 想要被序列化的类需要实现可序列化的接口 Serilizable

2. 完成序列化或者反序列化后 要将资源关闭

3. 最好自定义类的serialVersionUID

4. 对敏感字段数据可以选择使用瞬态关键字transient

反序列化读取时没有末尾的结束标记, 一旦读取到末尾就报异常, 因此不能使用循环读取

序列化后 反序列化前对类的组成部分做了更改, 导致serialVersionUID不一致, 会报错: 无效类异常

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值