Serializable/DeSerializable,序列化与反序列化

介绍:
1、参与序列化和反序列化的对象,必须实现 Serializable接口,否则会出现 java.io.NotSerializableException。

序列化,将 对象及信息 切割后 通过管道或者其它方式进行传输,写入文件之中

反序列化,将文件中 切割后的 对象及信息 重新恢复为 对应的对象及信息,在开发平台上运行

2、注意通过源代码发现,Serializable接口是一个标志接口: - public interface Serializable{}

- 实现这个接口之后会自动生成一个序列化版本号。

- 这个接口中什么代码都没有。那么他起到一个什么作用呢》

           起到标识的作用, 标识的作用,java虚拟机看到这个类实现了这个接口,可能会对这个类进行特殊待遇。

- Serializable这个标识接口是给java虚拟机参考的,java虚拟机看到这个接口之后, 会为该类自动生成一个序列化版本号。

3、序列化版本号有什么用?

用来区分类的。

        但是,实现之后Serializable接口会自动生成一个序列化版本号,

        这个 自动生成的序列化版本号 存在缺陷:同一个类但是由于序列化版本号不同,后续代码不能进行修改。因为只要一修改代码,需要重新编译,编译之后生成了全新的字节码文件,并且class文件再次运行时,java虚拟机生成的序列化版本号也会发生相应的改变,java虚拟机会认为这是一个全新的类。在修改代码之前序列化产生的文件,当使用固定的序列化版本号时,通过修改代码之后的反序列化程序,还是可以恢复之前的 对象及信息。

最终结论:

         凡是一个类实现了Serializable接口,建议给该类提供一个固定不变的序列化版本号。(最好配全球唯一,不过对于同一个项目,哪个数值都无所谓,只要手写,固定即可。)

       这样,以后这个类即使代码修改了,但是版本号不变,java虚拟机会认为这是同一个类。

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

        - 第一:首先通过类名进行比对,如果类名不一样,肯定不是同一个类

        - 第二:如果类名一样,在怎么进行类的区别呢?   靠 序列化版本号进行区分。

4、transient 关键字  ,表示 游离的。

设置某个对象中的某个属性不进行序列化,

        //简单的序列化步骤
        //创建java对象
        Student s1 = new Student(11,"zhangsan");
        //序列化,
        //创建一个输出流对象,并设置序列化后输出的文件名“students”
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("students"));

        //序列化对象
        oos.writeObject(s1);
        //刷新
        oos.flush();
        //关闭
        oos.close();

        //将上述经过序列化的对象,进行反序列化
        
        //创建一个输入流对象,并添加需要进行反序列化的文件名“students”
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("students"));
        //开始反序列化,读
        Object obj = ois.readObject();
        //反序列化回来是一个学生对象,所以会调用学生对象的toString()方法
        System.out.println(obj);
        //关闭流
        ois.close();

有多个对象需要序列化时,不能直接进行多个对象的序列化,需要使用List集合存放,然后进行序列化

        //多个对象的序列化步骤

        //创建一个集合对象,其中的元素为User对象
        List<User> list = new ArrayList<>();
        //添加元素
        list.add(new User(11,"zhangsan"));
        list.add(new User(22,"lisi"));
        list.add(new User(33,"wangwu"));

        //开始序列化
        //创就一个输出流对象,并添加序列化后输出的文件名“user”
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("users"));
        //序列化
        oos.writeObject(list);
        //刷新
        oos.flush();
        //关闭
        oos.close();

        //上述的多个对象序列化后进行 反序列化 的步骤

        //创建一个输入流对象,并添加进行反序列化的文件名“user”
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("users"));
        //反序列化
        List<User> userList= (List<User>)ois.readObject();
        
        //对其中的元素进行遍历
        for (User user:userList) {
            System.out.println(user);
        }
       // System.out.println(obj instanceof List);
        //关闭
        ois.close();

通过IDEA工具生成序列化版本号:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值