[转]关于 "the serializable class XXX does not declare a static final seriaVersionUID..."的问题 (2012-03-1

[转]关于  "the serializable class XXX does not declare a static final seriaVersionUID..."的问题

  (2012-03-16 21:44:47)
标签: 

serializable

 

杂谈

分类: Java

关于myeclips提示The serializable class XXX does not declare static final serialVersionUID field of type long的警告

我们在用eclips/myeclips的时候,会出现这个warning,比如在用hibernate时,自动生成表的对应类后,就有这个提示。这是为什么呢?

这与jdk的版本没关系,那是Eclipse提供的功能.
你点它warning的icon两下Eclipse就会自动给定,如果你不喜欢,可以把它关掉,
windows  ->  preferences  ->  compiler  ->  Error/Warnings  ->  Potential  Programming  problems
将Serializable  class  without  serialVersionUID的warning改成ignore.

其实如果你没有考虑到兼容性问题时,那就把它关掉吧.
其实有这个功能是好的.只要任何类别实作了Serializable这个介面,
如果没有加入serialVersionUID,Eclipse都会给你warning提示,
这个serialVersionUID为了让该类别Serializable後兼容.

考虑一下,如果今天你的类Serialized存到硬碟里,
可是後来你却更改了类别的field(增加或减少或改名).
当你Deserialize时,就会出现Exception.这样就会做成不兼容性的问题.

但当serialVersionUID相同时,它就会将不一样的field以type的预设值Deserialize.

这个可以避开不兼容性的问题.

================================================================

【Ohters】

对于“the serializable class XXXXXXXX  does not declare a static final seriaVersionUID field of type long”的警告

系统一直会提示三种快速解决方案:

1.add default serial version ID

2.add generated serial version ID

3.add "Suppress Warnings"  'servial' to XXXXXXXX

 一、前言

SerialVersionUid,简言之,其目的是序列化对象版本控制,有关各版本反序列化时是否兼容。如果在新版本中这个值修改了,新版本就不兼容旧版本,反序列化时会抛出InvalidClassException异常。如果修改较小,比如仅仅是增加了一个属性,我们希望向下兼容,老版本的数据都能保留,那就不用修改;如果我们删除了一个属性,或者更改了类的继承关系,必然不兼容旧数据,这时就应该手动更新版本号,即SerialVersionUid。

关于其定义,可参考JDK文档:http://download.oracle.com/javase/1.5.0/docs/api/java/io/Serializable.html

二、问题

1.如果不显式设置SerialVersionUid,有什么后果?

jdk文档中有解释,建议我们显式声明,因为如果不声明,JVM会为我们自动产生一个值,但这个值和编译器的实现相关,并不稳定,这样就可能在不同JVM环境下出现反序列化时报InvalidClassException异常。

...it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations...

2.两种SerialVersionUid有什么区别?

在Eclipse中,提供两种方式让我们快速添加SerialVersionUid。

add default serial version ID:
Adds a default serial version ID to the selected type
Use this option to add a user-defined ID in combination with custom serialization code if the type did undergo structural change since its first release.

add generated serial version ID:
Adds a generated serial version ID to the selected type
Use this option to add a compiler-generated ID if the type didnot undergo structural change since its first release.

一种就是1L,一种是生成一个很大的数,这两种有什么区别呢?

看上去,好像每个类的这个类不同,似乎这个SerialVersionUid在类之间有某种关联。其实不然,两种都可以,从JDK文档也看不出这一点。我们只要保证在同一个类中,不同版本根据兼容需要,是否更改SerialVersionUid即可。

对于第一种,需要了解哪些情况是可兼容的,哪些根本就不兼容。 参考文档:http://java.sun.com/j2se/1.4/pdf/serial-spec.pdf

在可兼容的前提下,可以保留旧版本号,如果不兼容,或者想让它不兼容,就手工递增版本号。

1->2->3.....

第二种方式,是根据类的结构产生的hash值。增减一个属性、方法等,都可能导致这个值产生变化。我想这种方式适用于这样的场景:

开发者认为每次修改类后就需要生成新的版本号,不想向下兼容,操作就是删除原有serialVesionUid声明语句,再自动生成一下。

个人认为,一般采用第一种就行了,简单。第二种能够保证每次更改类结构后改变版本号,但还是要手工去生成,并不是修改了类,会提示你要去更新这个SerialVersionUid,所以虽然看上去很cool,实际上让人很迷惑。

参考:

1.一篇较好的关于serialVesionUid的说明:

http://www.mkyong.com/java-best-practices/understand-the-serialversionuid/

2.serialVesionUid相关讨论

http://stackoverflow.com/questions/888335/why-generate-long-serialversionuid-instead-of-a-simple-1l

3.compiler-generated ID生成算法

http://java.sun.com/javase/6/docs/platform/serialization/spec/class.html#4100

其他相关问题:

Hibernate的持久化,这个一般指的是将数据持久化到数据库,和序列化并没有直接关系。

Hibernate的POJO也并不要求必须实现Serializable接口,但是,作为系统扩展考虑,应该把PO都实现Serializable接口,因为如果这些对象需要缓存到磁盘上,或者在分布式环境下使用,就必须序列化,最常见的例子就是ehcache、Memcached。key和value中的对象都必须是序列化的对象。

 

PS:原文地址http://hi.baidu.com/wojiubaibudu/blog/item/67aeb196eba8837e55fb968b.html


在 IntelliJ IDEA 中,可以通过配置来启用对未声明 `serialVersionUID` 字段的提示,尤其是在实现 `Serializable` 接口的类中。这种提示可以帮助开发者避免在类的序列化和反序列化过程中出现版本不一致的问题。 ### 启用 serialVersionUID 的警告提示 1. 打开 IntelliJ IDEA 的设置界面,可以通过菜单栏中的 **File → Settings**(在 Windows/Linux 上)或者 **IntelliJ IDEA → Preferences**(在 macOS 上)进入设置。 2. 在设置界面的搜索框中输入 **serialVersionUID**,快速定位到相关的配置选项。 3. 在搜索结果中找到 **Serializable class without 'serialVersionUID'** 的选项,并将其勾选。该选项通常位于 **Editor → Inspections** 的 Java 检查列表中。 4. 确认保存设置后,当实现 `Serializable` 接口的类未声明 `serialVersionUID` 字段时,IDEA 会在编辑器中标记出警告,提示开发者需要声明此字段。 ### 示例代码 以下是一个实现 `Serializable` 接口的类,并包含 `serialVersionUID` 字段的示例: ```java import java.io.Serializable; public class Person implements Serializable { private static final long serialVersionUID = 1L; private String name; private int age; // 构造函数、getter 和 setter 方法 public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } ``` ### 自动生成 serialVersionUID 字段 除了启用警告提示外,IntelliJ IDEA 还支持自动生成 `serialVersionUID` 字段的功能。在类中实现 `Serializable` 接口后,可以通过以下步骤快速生成该字段: 1. 将光标放置在类中的任意位置。 2. 使用快捷键 **Alt + Enter**(Windows/Linux)或 **Option + Enter**(macOS)打开快速修复菜单。 3. 选择生成 `serialVersionUID` 的选项,IDEA 会基于类的结构自动生成一个哈希值作为字段的值。 通过上述配置和操作,可以有效避免在实现 `Serializable` 接口时遗漏 `serialVersionUID` 字段的问题,从而提高代码的健壮性和兼容性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值