A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

序列化过程:序列化操作的时候系统会把当前类的serialVersionUID写入到序列化文件中,
            当反序列化时系统会去检测文件中的serialVersionUID,
            判断它是否与当前类的serialVersionUID一致,
            如果一致就说明序列化类的版本与当前类版本是一样的,可以反序列化成功,否则失败。
serialVersionUID有两种显示的生成方式:        
一是默认的1L,比如:private static final long serialVersionUID = 1L;        
二是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:        
    private static final long  serialVersionUID = xxxxL;
    1 当实现java.io.Serializable接口的类没有显式地定义一个serialVersionUID变量时候,
      Java序列化机制会根据编译的Class自动生成一个serialVersionUID作序列化版本比较用,
      这种情况下,如果Class文件(类名,方法明等)没有发生变化(增加空格,换行,增加注释等等),
      就算再编译多次,serialVersionUID也不会变化的。
    2 如果我们不希望通过编译来强制划分软件版本,即实现序列化接口的实体能够兼容先前版本,
      就需要显式地定义一个名为serialVersionUID,类型为long的变量,不修改这个变量值的序列化实体都可以相互进行串行化和反串行化。

当两次序列化的版本号serialVersionUID不一致时,会导致:   
[Java] 纯文本查看 复制代码
Exception in thread "main" java.io.InvalidClassException: com.demo.seriDemo.DataObject; local class incompatible: stream classdesc serialVersionUID = 1175939230834636559, local class serialVersionUID = -7343438723219659897



注意:
    (1)静态成员是不能被序列化的,因为静态成员是随着类的加载而加载的,与类共存亡,并且静态成员的默认初始值都是0;
     能被序列化的只是某个对象的成员.
    (2)如果同时在一次代码执行中进行序列化和反序列化,此时类中的静态成员是有值的,并不是因为静态的成员
     能够被序列化,而是此次运行jvm保存了静态成员。所以会发现好像静态成员被序列化和反序列化一样。
     
代码如下:
     
[Java] 纯文本查看 复制代码
public static void main(String[] args) throws Exception {
        // 序列化DataObject对象
       Serialize();
        // 反序列DataObject对象
        DataObject object = Deserialize();
        // 静态成员属于类级别的,所以不能序列化,序列化只是序列化了对象而已,
        // 这里的不能序列化的意思,是序列化信息中不包含这个静态成员域,下面
        // 之所以i输出还是2,是因为测试都在同一个机器(而且是同一个进程),因为这个jvm
        // 已经把i加载进来了,所以获取的是加载好的i,如果是传到另一台机器或者关掉程序重新
        // 写个程序读入DataObject.txt,此时因为别的机器或新的进程是重新加载i的,所以i信息就是初始时的信息,即0
        System.out.println(object);
    }
    /**
     * MethodName: SerializePerson
     * Description: 序列化对象
     * @author
     * @throws FileNotFoundException
     * @throws IOException
     */
    private static void Serialize() throws FileNotFoundException, IOException {
        DataObject object = new DataObject();
        object.setName("张三");
        object.setAge(10);
        // 创建ObjectOutputStream对象输出流,其中用到了文件的描述符对象和文件输出流对象
        ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(
                new File("DataObject.txt")));
        // 将DataObject对象存储到DataObject.txt文件中,完成对DataObject对象的序列化操作
        oo.writeObject(object);
        System.out.println("对象序列化成功!");
        // 最后一定记得关闭对象描述符!!!
        oo.close();
    }
    /**
     * MethodName: DeserializePerson
     * Description: 反序列DataObject对象
     * @author
     * @return
     * @throws Exception
     * @throws IOException
     */
    private static DataObject Deserialize() throws Exception, IOException {
        // 创建ObjectInputStream对象输入流,其中用到了文件的描述符对象和文件输入流对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
                new File("DataObject.txt")));
        // 从DataObject.txt文件中读取DataObject对象,完成对DataObject对象的反序列化操作
        DataObject object = (DataObject) ois.readObject();
        System.out.println("对象反序列化成功!");
        // 最后一定记得关闭对象描述符!!!
        ois.close();
        return object;
    }



3 个回复

倒序浏览
回复 使用道具 举报
拿起小本本学习一下,
回复 使用道具 举报
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马