关于serialVersionUID的解释

前两天升级了Eclipse到3.1版本,在老版本的IDE环境中写的程序在Problems中会出来好多类似的警告。当采用程序的自动修复时,采用默认方式,Eclipse会加上:private static final long serialVersionUID = 1L;

  其实这个问题倒也不影响程序的运行,但是我看到Problems里面有警告就不舒服,同时也说明我们写的代码还是不规范。不怕,我们有互联网查查是怎么回事,具体的原因还就是和序列化中的这个serialVersionUID有关。
  
  serialVersionUID 用来表明类的不同版本间的兼容性。如果你修改了此类, 要修改此值。否则以前用老版本的类序列化的类恢复时会出错。
  
  在JDK中,可以利用JDK的bin目录下的serialver.exe工具产生这个serialVersionUID,对于Test.class,执行命令:serialver Test。

  为了在反序列化时,确保类版本的兼容性,最好在每个要序列化的类中加入private static final long serialVersionUID这个属性,具体数值自己定义。这样,即使某个类在与之对应的对象已经序列化出去后做了修改,该对象依然可以被正确反序列化。否则,如果不显式定义该属性,这个属性值将由JVM根据类的相关信息计算,而修改后的类的计算结果与修改前的类的计算结果往往不同,从而造成对象的反序列化因为类版本不兼容而失败。

  不显式定义这个属性值的另一个坏处是,不利于程序在不同的JVM之间的移植。因为不同的编译器实现该属性值的计算策略可能不同,从而造成虽然类没有改变,但是因为JVM不同,出现因类版本不兼容而无法正确反序列化的现象出现。

  当我们的系统不太经常需要序列化类时,可以去掉这些警告,做如下设置:Window-->Preferences-->Java,将serializable class without serialVersionUID的设置由warning改为Ignore。然后Eclipse会重新编译程序,那些警告信息也就消失了。

  最后的建议是,如果我们开发大量需要序列化的类的时候,我们最好还是还原为原来的设置。这样可以保证系统的性能和健壮。

 

 

 

 

 

 

serialVersionUID 用来表明类的不同版本间的兼容性

简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。

当实现java.io.Serializable接口的实体(类)没有显式地定义一个名为serialVersionUID,类型为long的变量时,Java序列化机制会根据编译的class自动生成一个serialVersionUID作序列化版本比较用,这种情况下,只有同一次编译生成的class才会生成相同的serialVersionUID 。

如果我们不希望通过编译来强制划分软件版本,即实现序列化接口的实体能够兼容先前版本,未作更改的类,就需要显式地定义一个名为serialVersionUID,类型为long的变量,不修改这个变量值的序列化实体都可以相互进行串行化和反串行化。

 

 

 

 

 

 

 

 

 

 

 

http://hi.baidu.com/%CD%A2%C9%AD/blog/item/14663ef1172f08a7a40f52c8.html

JAVA类实现序列化的方法
2009-04-03 16:22

Java中通过implements Serializable来实现对象的序列化。其实Serializable接口中并没有需要实现的方法,注明某个类implements Serializable只是为了标识或表明这个类可以被序列化。
       那么什么是序列化呢,序列化又有什么作用呢?
       一个类,或对象能够被序列化表明这个类或对象能过转化成数据流的形式。之所以要转化为数据流是为了在数据传输(特别是IO操作和网络传输)中对流化(序列化)的对象进行读写操作。也就是说序列化是为了解决在对对象流进行读写操作时所引发的问题。

       JAVA中实现序列化的基本过程是:
      (1)将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements       Serializable只是为了标注该对象是可被序列化的,
      (2)然后使用一个输出流(如:FileOutputStream)来构造一个 ObjectOutputStream(对象流)对象
      (3)接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写               出(即保存其状态),要恢复的话则用输入流。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
private static final long serialVersionUID = 1L; 这段代码是用来指定序列化版本号的。在Java中,当一个对象需要被序列化(即转换为字节流以便存储或传输)时,会将对象的状态保存为字节序列。而在反序列化时,会将字节序列转换回对象的状态。为了确保反序列化的成功,Java使用了一个称为serialVersionUID的标识符来识别序列化对象的版本。 serialVersionUID是一个长整型的常量,用于唯一标识一个类的序列化版本。当一个类被序列化时,会将serialVersionUID一同写入序列化数据中。在反序列化时,会将读取到的serialVersionUID与当前类的serialVersionUID进行比较,如果两者不一致,则会抛出InvalidClassException异常,表示版本不兼容。 通过显式地声明serialVersionUID,可以确保在类的结构发生变化时,仍然能够正确地反序列化旧版本的对象。如果不显式声明serialVersionUID,Java会根据类的结构自动生成一个默认的serialVersionUID,但这样会导致在类的结构发生变化时,反序列化可能会失败。 因此,为了保证序列化和反序列化的兼容性,一般建议在可序列化的类中显式地声明private static final long serialVersionUID = 1L;。这样可以确保在类的结构发生变化时,仍然能够正确地反序列化旧版本的对象。 #### 引用[.reference_title] - *1* *3* [private static final long serialVersionUID = 1L的解释;【通俗易懂】](https://blog.csdn.net/weixin_43899069/article/details/121118234)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [每日解惑:private static final long serialVersionUID = 1L](https://blog.csdn.net/qq_33331448/article/details/120536274)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值