IO流--序列化流与反序列化流

本文详细介绍了Java对象序列化的过程,包括实现Serializable接口、生成序列号解决InvalidClassException异常、使用transient关键字保护敏感数据等关键步骤。同时,探讨了序列化在数据安全性和持久化方面的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.让要写入的类实现 Serializable接口,这是一个标记接口,只有实现了这个接口的类才能被序列化,这个思想类似于Cloneable接口,实现了这个接口就表示可以被克隆

/*  (1)如果没有实现,此时会报出没有序列化异常    NotSerializableException,需要让要写入的对象
 实现序列化接口*/
class Student implements Serializable {//实现序列化接口Serializable 
    
    private String name;
    private Integer  age;

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

}

(2)
新建一个写的方法

public static void write()throws Exception{
        //需求:要把对象写入到文件:stu.txt中
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("stu.txt"));
        Student stu=new Student("张三",14);
        oos.writeObject(stu);
    }

效果:
在这里插入图片描述
(3)这样就成功了,但会发现文件中的对象是乱码的,这个没有关系,这个是系统本身的设计,是为了让数据更加安全,如果我们想把它读出来.可以使用 ObjectInputStream 这个流,即反序列化
新建一个读的方法:

    public static void read()throws Exception{
        //这样就写入成功了,我们可以通过反序列化把它读取出来
  ObjectInputStream ois=new ObjectInputStream(new     FileInputStream("stu.txt"));
        Object obj=ois.readObject();
        if(obj instanceof Student){
            Student stu1=(Student)obj;
            System.out.println(stu1.getName()+"|"+stu1.getAge());
        }
    }
}

效果:
在这里插入图片描述
(4)至此,已经写完和读完了,但是仍然存在两个隐患,需要我们去完善
问题一:如果我写完后,修改了类中的任意一个地方,再去读,就会发现读不出来了,会报InvalidClassException:这样一个异常
原因分析:我们来理一下刚才的操作:
第一步:
我们在通过序列化流将对象写入文件,那么这个对象保存在文件中,会有一个编号来标识对象

stream classdesc serialVersionUID = 1268963545368942282
local class serialVersionUID=1268963545368942282

第二步:
我们通过反序列化流读取文件,在反序列化之前,会先判断文件中的对象的序列化ID和本地class文件的序列化ID是否匹配,如果匹配,则反序列化对象
第三步:
修改了源文件后,重新编译java,生成class文件,重新生成class序列化id,local class serialVersionUID = -7770128259322463329
第四步:
当你在反序列化的时候,会先判断文件中的对象序列化id和本地class文件的序列化id是否匹配,不匹配,就会排除异常:InvalidClassException

解决办法:
让序列化持久化,在要序列化的类中加一个序列号成员变量,这样要通过快捷键生成
方法:选中类名,按alt+enter
在这里插入图片描述
如果没有出现这个,可以根据以下图片进行配置
在这里插入图片描述
效果如下:
在这里插入图片描述
这样就解决了问题一了
问题二:既然我们对象写入文件中会乱码是为了安全,那我们可以通过反序列化流将数据读取出来,岂不是又让数据不安全了,
解决办法:在不想被读取出来的成员变量中加修饰符:transient,这样读取出来就是null了
在这里插入图片描述
效果:
在这里插入图片描述

总结:
三个步骤:
(1)实现序列化接口,异常:NotSerializableException
(2)生成序列号:InvalidClassException
(3)加transient修饰符,让数据变安全:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值