serialVersionUID的作用以及IDEA、Eclipse如何自动生成serialVersionUID
说到serialVersionUID,首先要讲讲序列化。
序列化:
序列化可以将一个java对象以二进制流的方式在网络中传输并且可以被持久化到数据库、文件系统中,反序列化则是可以把之前持久化在数据库或文件系统中的二进制数据以流的方式读取出来重新构造成一个和之前相同内容的java对象。
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。
把Java对象转换为字节序列的过程称为对象的序列化。
把字节序列恢复为Java对象的过程称为对象的反序列化。
序列化的作用:
第一种:用于将java对象的字节序列保存到硬盘上储存起来,通常放到一个文件中,使下次需要用到的时候再读取到它之前的信息。
第二种:可以让java对象的字节序列在网络中传输。
序列化的实现:
)、只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式,该接口没有任何方法,只是标示该类对象可被序列化。
2)、序列化过程:使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。 )、反序列化过程:使用一个输入流(如:FileInputStream)来构造一个ObjectInputStream(对象流)对象,接着,使用ObjectInputStream对象的readObject(Object obj)方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
在java源代码中Serializable的源代码是以下
public interface Serializable {
}
为什么实现了Serializable 一个空的接口,就可以序列化呢?
Serializable接口不是为了解耦,恰恰是使得程序和jvm耦合吧。
Serializable接口是一种与虚拟机的约定,实现了Serializable接口的类就像是告诉虚拟机“让我具有飞翔的能力”,然后jvm就给了你的类飞翔的能力。
我觉得Serializable和public/static/final/int/synchronized关键字没有区别,都是程序与jvm的约定,或者广义的说“接口”。可以把 serializable看成是java语言级别的或都说是jvm的系统接口
凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:private static final long serialVersionUID; 这个值可以由类指定,也可以不指定。如果不指定的话java会根据class计算serialVersionUID
serialVersionUID是可序列化类的一个版本标识,在反序列化的时候使用这个标识的值来判断序列化和反序列化的对象类型是否一致。Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常(InvalidClassException)。当你一个类实现了Serializable接口,如果没有定义serialVersionUID,编辑器就会提供这个提示功能告诉你去定义之。
类的serialVersionUID的默认值完全依赖于Java编译器的实现,对于同一个类,用不同的Java编译器编译,有可能会导致不同的serialVersionUID,也有可能相同。为了提高serialVersionUID的独立性和确定性,强烈建议在一个可序列化类中显示的定义serialVersionUID,为它赋予明确的值。显式地定义serialVersionUID有两种用途:
1)在某些场合,希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID;在某些场合,不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有不同的serialVersionUID。
2)当你序列化了一个类实例后,希望更改一个字段或添加一个字段,不设置serialVersionUID,所做的任何更改都将导致无法反序化旧有实例,并在反序列化时抛出一个异常。如果你添加了serialVersionUID,在反序列旧有实例时,新添加或更改的字段值将设为初始化值(对象为null,基本类型为相应的初始默认值),字段被删除将不设置。
当系统不需要序列化类时,可以去掉这些警告,做如下设置:Window-->Preferences-->Java,将serializable class without serialVersionUID的设置由warning改为Ignore。然后Eclipse会重新编译程序,那些警告信息也就消失了。
如果没有设置这个值,你在序列化一个对象之后,改动了该类的字段或者方法名之类的,那如果你再反序列化想取出之前的那个对象时就可能会抛出异常,因为你改动了类中间的信息,serialVersionUID是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,当修改后的类去反序列化的时候发现该类的serialVersionUID值和之前保存在问价中的serialVersionUID值不一致,所以就会抛出异常。
Eclipse中有两种生成方式:
一个是默认的1L,比如:“private static final long serialVersionUID = 1L;";
一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:“private static final long serialVersionUID = -8940196742313994740L;”。
使用serialVersionUID要注意以下几点:
1.当实现java.io.Serializable接口的实体(类)没有显式地定义一个名为serialVersionUID,类型为long的变量时,Java序列化机制会根据编译的class自动生成一个serialVersionUID作序列化版本比较用,这种情况下,只有同一次编译生成的class才会生成相同的serialVersionUID 。如果我们不希望通过编译来强制划分软件版本,即实现序列化接口的实体能够兼容先前版本中未作更改的类,就需要显式地定义一个名为serialVersionUID,类型为long的变量,不修改这个变量值的序列化实体都可以相互进行串行化和反串行化。
2.记住应该总是在可序列化的类中包含这个字段,即使是在第一个类版本中,以便提醒自己这个字段的重要性。不要在未来的版本中改变这个字段值,除非你有意要改变类使其与旧的序列化对象不兼容。
3.如果你的类序列化到硬盘上面后,你更改了类别的field(增加或减少或改名),当你反序列化时,就会出现异常的,这样就会造成不兼容性的问题。但当serialVersionUID相同时,它就会将不一样的field以type的预设值Deserialize,这个可以避开不兼容性的问题。
4.当我们的系统不太经常需要序列化类时,可以去掉这些警告,做如下设置:Window-->Preferences-->Java,将serializable class without serialVersionUID的设置由warning改为Ignore。然后Eclipse会重新编译程序,那些警告信息也就消失了。但如果在开发大量需要序列化的类的时候,建议还原为原来的设置。这样可以保证系统的性能和健壮。
serialVersionUID的作用以及IDEA、Eclipse如何自动生成serialVersionUID的更多相关文章
- serialVersionUID的作用以及如何用idea自动生成实体类的serialVersionUID
转载:http://blog.csdn.net/liuzongl2012/article/details/45168585 serialVersionUID的作用: 通过判断实体类的serialVer ...
- eclipse中自动生成serialVersionUID
serialVersionUID作用: 序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性. 如果你修改代码重新部署后出现序列化错误,可以考虑给相应的类增加seri ...
- IntelliJ IDEA 中自动生成 serialVersionUID 的方法
as, idea plugin中搜如下关键字,并安装该插件: GenerateSerialVersionUID 如上图所示,创建一个类并实现Serializable接口,然后按alt+Enter键,即 ...
- IDEA设置换行符为Unix编码格式,设置编码统一为UTF-8,自动生成serialVersionUID
设置换行符为Unix编码格式 设置编码统一为UTF-8 自动生成serialVersionUID.勾选"Serializable class without serialVersionUID ...
- idea自动生成serialVersionUID , serialVersionUID的作用
Java的序列化的机制通过判断serialVersionUID来验证版本的一致性.在反序列化的时候与本地的类的serialVersionUID进行比较,一致则可以进行反序列化,不一致则会抛出异常Inv ...
- Intellij IDEA 自动生成 serialVersionUID
转 Intellij IDEA 自动生成 serialVersionUID 收藏 tonycody 发表于 2年前 阅读 18399 收藏 5 点赞 2 评论 0 使用 Eclipse 或 MyEcl ...
- IDEA 自动生成serialVersionUID
场景:刚转到用IDEA,因为需要生成serialVersionUID,并没有自动生成. 转自:http://blog.csdn.net/liuzongl2012/article/details/451 ...
- IDEA使用笔记(八)——自动生成 serialVersionUID 的设置
这个设置比较简单,也有一些博文已经写到了,为什么我还要写哪?(潜台词:因为我想凑一篇博文)我觉得学习,特别是编程学习是需要重复造轮子的,另外,就是加深自己的印象方便自己的查找.还有就是关键点,有些博客 ...
- 二十四、详述 IntelliJ IDEA 中自动生成 serialVersionUID 的方法
当我们用 IntelliJ IDEA 编写类并实现 Serializable(序列化)接口的时候,可能会遇到这样一个问题,那就是: 无法自动生成serialVersionUID. 而serialVer ...
随机推荐
- streamsets http client && json parse && local fs 使用
streamsets 包含了丰富的组件,origin processer destination 测试例子为集成了http client 以及json 处理 启动服务 使用docker 创建pipel ...
- sysstat工具
sysstat工具可以监控系统的IO,CPU,SWAP,LOAD,NETWORK,DISK 安装后,系统会生成定时任务脚本 路径:/etc/cron.d/sysstat 内容: # Run syste ...
- [LeetCode系列] 跳跃问题II
给定一系列非负整数, 每个值代表从此下标可以向前跳跃的最远距离, 试求出跳跃到数组尾端需要的最少步骤. 如给定 [2,3,1,1,4], 返回2. (从下标0跳到1, 从1跳到下标4). 算法描述: ...
- linux Posix 信号量 一
信号量是一种用于提供不同进程间或一个给定进程的不同线程间同步手段的原语. linux提供两种信号量,“内核信号量”和“用户态进程信号量”,“用户态信号量”又分为“Posix”,“System V”信号 ...
- (转)C#与Outlook交互收发邮件
本文转载自:http://www.cnblogs.com/Moosdau/archive/2012/03/11/2390729.html .Net对POP3邮件系统已经集成了相应的功能,但是如果是基于 ...
- 介绍一个开源的 C++ 开发框架 openFrameworks 。
作为一个图形图像方向的研究生,我经常都在和 OpenGL .OpenCV 等多种 C++ 库打交道.这些库遵循着不同的规则和用法:另外,为了让自己的程序具有更多的交互能力,编写界面也是一个家常便饭的工 ...
- mysql为什么会慢
--2019.4.18 mysql技术大会分享--叶金荣mysql为什么会慢性能瓶颈分析.排查思路 先确认一下真的是mysql响应慢了吗导致mysql慢可能会有那些因素呢?--资源稀缺 ---cpu, ...
- MySql存储过程简单实例
转自:http://www.cnblogs.com/zhuawang/p/4185302.html ********************* 创建表 ************************ ...
- Unity容器声明周期管理
Having said that, here is a solution that you can use with the Unity container: Create some custom a ...
- Bootstrap的介绍和响应式媒体查询
Bootstrap的介绍 凡是使用过Bootstrap的开发者,都不在乎做这么两件事情:复制and粘贴.哈哈~,是的使用Bootstrap非常简单,但是在复制粘贴之前,需要先对Bootstrap的用法 ...