• 文件输入和输入出处理(六)-序列化和反序列化


    序列号

    • 序列号是序列化和反序列化的唯一标识,是一个长整型数值
    • 如果类中不自己定义序列号,系统会自动生成一个序列号
    • 当一方实体类发生改变,而调用方的序列号是不会跟着改变的,不知道对象已修改,会导致两边序列号不一致,反序列化失败;
    • 所以要求必须手动生成一个序列号
    • 手动生成序列号后,可以解决目标类发生改变,不影响接口调用,对象可以正确序列化,不过对象修改的属性返序列化后没有值;

    序列化对象类

    //如果要支持序列化操作必须实现序列化接口
    //账户类
    public class Account implements Serializable {
    	//手动生成序列号
        private static final long serialVersionUID = 2116137267832764072L;
        
        //账户名
        private  String aname;
    
        //账户密码
        private String apwd;
        
        //set,get方法省略
        
        @Override
        public String toString() {
            return "Account{" +
                    "aname='" + aname + '\'' +
                    ", apwd='" + apwd + '\'' +
                    '}';
        }
    }    
    

    序列化

    使用ObjectOutputStream 类的 writeObject(Object obj)方法

    //序列化对象,写入文件
    public static void xlhAccount() throws IOException {
        Account account = new Account("KH96","12345");
    
        //使用对象输出流,将内存中的对象写入到文件
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:/test/account.txt"));
        
        //直接写入对象
        oos.writeObject(account);
    
        oos.close();
        System.out.println("序列化对象写入成功");
    }
    

    序列化结果

    反序列化

    使用 ObjectInputStream 类的 readObject()方法

    //反序列化目标对象读取写入序列化的文件,进行反序列化,变为写入的那个目标对象
    public static void fxlhAccount() throws IOException, ClassNotFoundException {
        //使用对象输入流,读入写入了序列化对象的文件
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/test/account.txt"));
        
        Account account = (Account) ois.readObject();
        ois.close();
        
        //输出目标对象
        System.out.println(account.toString());
    
        System.out.println("读取序列化对象,反序列化成功");
    
    }
    

    反序列化结果

    Account{aname='KH96', apwd='12345'}
    读取序列化对象,反序列化成功
    

    当类发生改变

    改变后的序列化对象

    //账户类
    public class Account implements Serializable {
    	//手动生成序列号
        private static final long serialVersionUID = 2116137267832764072L;
        
        //账户名
        private  String aname;
        
        //账户密码
        private String apwd;
    
        //添加手机
        private  String atel;
        
        //set,get方法省略
        
        @Override
        public String toString() {
            return "Account{" +
                    "aname='" + aname + '\'' +
                    ", apwd='" + apwd + '\'' +
                    ", atel='" + atel + '\'' +
                    '}';
        }
    }
    

    反序列化结果

    Account{aname='KH96', apwd='12345', atel='null'}
    读取序列化对象,反序列化成功
    

    如果没有手动声明序列号,实体类发生改变后就会java.io.InvalidClassException异常,序列号不一致而无法进行序列化。

  • 相关阅读:
    Linux 系统中查看和停止删除定时任务
    worthington是谁?worthington抑制剂对酶活性的影响研究
    完全卸载mysql
    【从零开始学微服务】02.初识微服务
    研究前沿| Nature:艰难梭菌引发肠道神经源性炎症的新机制
    公众号如何让更多人看到?这三种方法超有效!
    绘画系统(01):【纲】Paint System[官翻]
    HTTP,HTTPS,WebSocket协议辨析
    shell 编程简记
    「地埋式积水监测站」智慧防汛,科技先行
  • 原文地址:https://www.cnblogs.com/xiaoqigui/p/16393040.html