zoukankan      html  css  js  c++  java
  • Java I/O流操作(四)对象的序列化

     
     首先,把对象序列化必须实现Serializable接口, 只有这样才能把对象持久化到硬盘获取其他地方.
     
    对象序列化操作需要使用到ObjectOutputStream和ObjectInputStream两个对象
    ObjectOutputStream ( OutputStream  out)
    创建一个ObjectOutputStream 把对象往OutputStream输出流写入
    ObjectOutputStream也是字节输出流的子类:
    java.lang.Object
      java.io.OutputStream
          java.io.ObjectOutputStream
    
    ObjectInputStream是字节输入流的子类:
    java.lang.Object
      java.io.InputStream
          java.io.ObjectInputStream
    
    ObjectOutputStream通过writeObject(Object obj) 
    ObjectInputStream通过readObject() 
    通过一个简单的程序测试:

    publicstaticvoid objetcSeri()throws Exception {

        ObjectOutputStream oos =new ObjectOutputStream(
        new FileOutputStream("person.object"));
        //写入person对象
        oos.writeObject(new Person("johnny",21,"CHINA"));
        oos.close();

    }

    控制台 出现如下错误:
    Exception in thread "main" java.io.NotSerializableException: com.huaxia.day21.Person
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at com.huaxia.day21.ObjectSerializable.objetcSeri(ObjectSerializable.java:15)
    at com.huaxia.day21.ObjectSerializable.main(ObjectSerializable.java:9) 
    说明Person这个类没有实现Serializable接口
    更正错误后发现硬盘中多了一个person.obejct文件
    其内容为一些我们看不懂的字符:

     

    那么我们是否通过ObjectInputStream读取到文件的内容呢?
    publicstaticvoid readObject() throws Exception {
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.object"));
    Person person = (Person)ois.readObject();
    System.out.println(person);
    } 
    控制台输出结果:name:johnny age:21 country:CHINA 
    我们来看一下Serializable接口的API

     

    这意思是说:如果实现了序列化接口的类没有显示声明serialVersionUID变量,序列化运行时将计算一个默认的serialVersionUID的值为这个类基于类的变量方面的值
    .我们强烈建议所有实现序列化接口的类都要显示的声明serialVersionUID变量,因为默认的serialVersionUID变量值对于类的修改是非常敏感的,因为他的值就是根据
    类成员的签名而生成的而不是系统随机生成的,假设我们对类A进行序列化,在一般情况下我们可以反序列化得到类A的信息,如果我们一旦修改了类A,
    那么我们再次反序列化就会出现java.io.InvalidClassException 异常的,因为第一次编译类A的时候他的id是一个值,
    你修改类A后在再次编译id的值已经变了.因此为了保证在不同的编译器serialVersionUID变量的值一致性,
    所以建议把该变量定义成一个private的常量.
    下面来模拟这种情况:现在我修改Person类:如下

     

     重新反序列化一次:
     
    publicstaticvoid readObject() throws Exception {
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.object"));
    Person person = (Person)ois.readObject();
    System.out.println(person);
    } 
     控制台打印店异常:Exception in thread "main" java.io.InvalidClassException: com.huaxia.day21.Person; local class incompatible: 
    stream classdesc serialVersionUID = -379036032685453711, 
    local class serialVersionUID = 1208026685571330753 
     
     
     
    总结: 对象持久化需要实现Serializable接口, 并且声明serialVersionUID常量
     
    转载请注明出处: http://blog.csdn.net/johnny901114/article/details/8710341
     
     
  • 相关阅读:
    用prototype属性来模拟一下类的继承
    Ajax 教程:Ajax 入门简介
    Ajax工作原理
    最新的Ajax教程和技术(上篇)
    javascript面向对象技术基础
    浏览器对象模型
    jQuery (选择器,属性,筛选,文档处理)
    shell(一)
    ntpntpdate时间同步
    centos7新系统安装
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/2979654.html
Copyright © 2011-2022 走看看