serialVersionUID:字面意思上是序列化的版本号,这个在刚刚接触java编程时,学序列化大家一般都不会注意到,在你一个类序列化后除非你强制去掉了myeclipse中warning的功能,在你实现序列化的类上会有这个警告,点击会出现增加这个版本号。

说说这个版本号得作用:就是确保了不同版本之间的兼容性,不仅能够向前兼容,还能够向后兼容,即在版本升级时反序列化仍保持对象的唯一性。

它有两种生成方式:

     

      一个是默认的1L,比如:private staticfinal long serialVersionUID = 1L;

      一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:  privatestatic final long serialVersionUID = xxxxL;

从两个例子上来说明这个序列化号的作用:

     这是一个类实现了序列化,但是并没有显式的声明序列号,在这里说明一下,如果没有显式声明序列号,那么在程序编译时会自己生成这个版本序列号,

     程序1

     public class Animal implements Serializable{



    publicString name;



    publicString no;



    

    }

    

    通过这个程序来将上面的一个实体存起来:程序2

    public static void main(String[] args) throws Exception{

    Animal an =new Animal();

   FileOutputStream f = newFileOutputStream("foo");

   ObjectOutputStream oos = newObjectOutputStream(f);

   oos.writeObject(an);

   oos.close();

     }

    通过这个程序读取出刚才存储的类:程序3

    public static void main(String[] args) throws Exception{

       FileInputStream fis = newFileInputStream("foo");

   ObjectInputStream ois = newObjectInputStream(fis);

    

       Animal ani = (Animal)ois.readObject();

       ois.close();

       fis.close();   

    }

    这种编译是成功的,但是当你在程序1中的类增加一个成员变量的时候,在运行程序3,就会报错:

     Exception in thread "main" java.io.InvalidClassException:koal.Animal;……

    atjava.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:562)

    atjava.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1583)

    atjava.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496)

    atjava.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732)

    atjava.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)

    atjava.io.ObjectInputStream.readObject(ObjectInputStream.java:351)

    atkoal.SerialVersion.main(SerialVersion.java:22)

   这是为什么呢?

   因为在你没有显式的声明序列号时,在程序编译时候会自动生成一个序列号,存储在文件中,但是在你更改了实体类的时候又会重新生成一个序列号,在程序运行的时候,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。也就是说,在你读取这个object的时候,他会比较你的现在这个类的序列号和你存储的那个序列号是否相等,如果相等,则说明这是同一个版本,如果不相等则是不同版本,不同版本之间的成员变量是不相同的,所以就会报错,但是当你显式的声明了这个序列号时,不论你如何修改类中的成员变量还是方法,都不会引起版本之间不兼容得问题,这个就加强了你的程序的健壮性。

   在很多地方我们都会用到这个序列化,例如在游戏中,游戏升级之后,还要能够让程序成功读取以前的数据,让升级之后的程序还能认识以前的数据文件,即使数据格式不一致,也不会丢失数据。

  像一些持久化的配置文件,中途要升级,增加属性,都要使用这个版本序列号,在这里我们是希望程序中只要是实现序列化的类都最好是显式的声明这个序列版本号。

序列化与反序列化中serialVersionUID的作用(通俗易懂)的更多相关文章

  1. java序列化和反序列化中的serialVersionUID有啥用

     1.什么是序列化和反序列化 序列化就是将java对象转成字节序列的过程:反序列化就是将字节序列转成java对象的过程. java中,序列化的目的一种是需要将对象保存到硬盘上,一种是对象需要在网络中传 ...

  2. java.io.Serializable中serialVersionUID的作用

    把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中: 2) 在网 ...

  3. JAVA中序列化和反序列化中的静态成员问题

    关于这个标题的内容是面试笔试中比较常见的考题,大家跟随我的博客一起来学习下这个过程. ? ? JAVA中的序列化和反序列化主要用于: (1)将对象或者异常等写入文件,通过文件交互传输信息: (2)将对 ...

  4. Q:java中serialVersionUID的作用

    @转载自:http://www.cnblogs.com/guanghuiqq/archive/2012/07/18/2597036.html   简单来说,Java的序列化机制是通过在运行时判断类的s ...

  5. Java中的序列化与反序列化

    序列化定义 将对象转换为字节流保存起来,并在以后还原这个对象,这种机制叫做对象序列化. 将一个对象保存到永久存储设备上称为持久化. 一个对象要想能够实现序列化,必须实现java.io.Serializ ...

  6. c# 通过json.net中的JsonConverter进行自定义序列化与反序列化

    https://www.cnblogs.com/yijiayi/p/10051284.html 相信大家在工作中会经常遇见对json进行序列化与反序列化吧,但通常的序列化与反序列化中的json结构与c ...

  7. serialVersionUID的作用以及设置方法(转)

    声明:本篇文章是转载的 http://blog.csdn.net/kakaxi_77/article/details/8129070 http://snowlotus.iteye.com/blog/2 ...

  8. 序列化和反序列化为什么要实现Serializable接口?(史上最全、简单易懂)

    目录结 前言 1.什么是序列化和反序列化 2.什么时候需要进行序列化和反序列化 2.1.服务器和浏览器交互时用到了Serializable接口吗? 2.2.Mybatis将数据持久化到数据库中用到了S ...

  9. Hessian 序列化和反序列化实现

    先聊聊 Java的序列化,Java官方的序列化和反序列化的实现被太多人吐槽,这得归于Java官方序列化实现的方式. 1.Java序列化的性能经常被吐槽.2.Java官方的序列化后的数据相对于一些优秀的 ...

随机推荐

  1. C stat函数的用法举例(转载)

    stat函数讲解表头文件:    #include <sys/stat.h>             #include <unistd.h>定义函数:    int stat( ...

  2. 用premake5创建lua532工程

    用premake5创建lua532工程 (金庆的专栏) lua-5.3.2只有Makefile,根据readme.html中"Building Lua on other systems&qu ...

  3. Python descriptor

    class A: def __init__(self, name): self.name = name def __get__(self, ins, cls): print('call get') i ...

  4. Linux telnet远程登录操作

    telnet  (如果不行 可以却换root帐户试试 su - root) 1.安装telnet-server     sudo dpkg -i xinetd_1%3a2.3.14-7ubuntu3_ ...

  5. cassandra 如何写数据以及放置副本

    application发送数据到server application 发送请求到server 根据设置的load balance 规则从cluster中挑选一个coordinator,一般使用轮询即可 ...

  6. C/C++的mem函数和strcpy函数的区别和应用

    mem系列函数是面试的时候常考的知识点,我们需要熟练掌握这三个函数的原理和代码实现,要能准确无误的写出代码. memcpy.memset和memset三个函数在使用过程中,均需包含以下头文件: //在 ...

  7. 1026. Table Tennis (30)

    题目如下: A table tennis club has N tables available to the public. The tables are numbered from 1 to N. ...

  8. HTML5中 HTML表单和PHP环境搭建及与PHP交互 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博! 知识点概括:HTML表单/PHP环境搭建/表单提交数据与PHP交互 第一部分:HTML表单 <!DOCTYP ...

  9. 百度地图隐藏缩放控件比例尺Logo

    对于百度地图最新版V3.7.3,以前的隐藏控件方法失效,可用以下方法隐藏: 1.隐藏缩放控件: mMapView.showZoomControls(false); 2.隐藏比例尺: mMapView. ...

  10. 【一天一道LeetCode】#371. Sum of Two Integers

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Calcula ...