序列化版本号serialVersionUID的作⽤_动⼒节点Java学院
整理
Java序列化是将⼀个对象编码成⼀个字节流,反序列化将字节流编码转换成⼀个对象。序列化是Java中实现持久化存储的⼀种⽅法;为数据传输提供了线路级对象表⽰法。
Java的序列化机制是通过在运⾏时判断类的serialVersionUID来验证版本⼀致性的。在进⾏反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进⾏⽐较,如果相同就认为是⼀致的,可以进⾏反序列化,否则就会出现序列化版本不⼀致的异常。
Eclipse中The serializable class XXXXXX  does not declare a static final serialVersionUID field of type long出现这样的警告处理办法。
当采⽤程序的Add default Serial version ID修复时,Eclipse会加上:private static final long serialVersionUID = 1L;
当采⽤程序的Add generated Serial version ID修复时,Eclipse会加上:private static final long serialVersionUID = xxxxL;
其实这个问题出现的具体原因是和序列化中的这个serialVersionUID有关。 serialVersionUID ⽤来表明类的不同版本间的兼容性。有两种⽣成⽅式:⼀个是默认的1L;另⼀种是根据类名、接⼝名、成员⽅法及属性等来⽣成⼀个64位的哈希字段。在JDK中,可以利⽤JDK的bin⽬录下的⼯具产⽣这个serialVersionUID 的值,对于Test.class,执⾏命令:serialver Test  这时JVM(java虚拟机)会⽣成⼀个哈希字段。
对⽐⼀下这个哈希字段的值与⽅法2中⽣成的字段值是⼀样的,可见,在CMD中使⽤serialver指令就是根据类名、接⼝名、成员⽅法及属性等来⽣成哈希字段的。
java类中为什么需要重载 serialVersionUID 属性。java重载
当两个进程在进⾏远程通信时,彼此可以发送各种类型的数据。⽆论是何种类型的数据,都会以⼆进制序列的形式在⽹络上传送。发送⽅需要把这个Java对象转换为字节序列,才能在⽹络上传送;接收⽅则需要把字节序列再恢复为Java对象。把Java 对象转换为字节序列的过程称为对象的序列化,把字节序列恢复为Java对象的过程称为对象的反序列化。
  对象的序列化主要有两种⽤途:
  1)把对象的字节序列永久地保存到硬盘上,通常存放在⼀个⽂件中;
  2)在⽹络上传送对象的字节序列。
java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)⽅法可对参数指定的obj对象进⾏序列化,把得到的字节序列写到⼀个⽬标输出流中。 java.io.ObjectInputStream代表对象输⼊流,它的readObject()⽅法从⼀个源输⼊流中读取字节序列,再把它们反序列化为⼀个对象,并将其返回。只有实现了Serializable或Externalizable接⼝的类的对象才能被序列化。Externalizable接⼝继承⾃Serializable接⼝,实现Externalizable接⼝的类完全由⾃⾝来控制序列化的⾏为,⽽仅实现Serializable接⼝的类可以采⽤默认的序列化⽅式。凡是实现Serializable接⼝的类都有⼀个表⽰序列化版本标识符的静态变量:private static final long serialVersionUID; 类的serialVersionUID的默认值完全依赖于Java编译器的实现,对于同⼀个类,⽤不同的Java编译器编译,有可能会导致不同的serialVersionUID。显式地定义serialVersionUID有两种⽤途:
  1)在某些场合,希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID;在某些场合,不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有不同的serialVersionUID。
  2)当你序列化了⼀个类实例后,希望更改⼀个字段或添加⼀个字段,不设置serialVersionUID,所做的任何更改都将导致⽆法反序化旧有实例,并在反序列化时抛出⼀个异常。如果你添加了serialVersionU
ID,在反序列旧有实例时,新添加或更改的字段值将设为初始化值(对象为null,基本类型为相应的初始默认值),字段被删除将不设置。
序列化算法⼀般会按步骤:
将对象实例相关的类元数据输出。
递归地输出类的超类描述直到不再有超类。
类元数据完了以后,开始从最顶层的超类开始输出对象实例的实际数据值。
从上⾄下递归输出实例的数据
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。