【转载】Understand the serialVersionUID
If you have ever implemented Serializable interface, you must encounter this warning message
The serializable class xxx does not declare a static final serialVersionUID field of type long
So…what is serialVersionUID?
The serialVersionUID is used as a version control in a Serializable class. If you do not explicitly declare a serialVersionUID, JVM will do it for you automatically, based on various aspects of your Serializable class, as described in the Java(TM) Object Serialization Specification.
1. SerialVersionUID Example
The above statement is a bit hard to understand at the beginning (at least I did), let start an example to understand how Serializable class use SerialVersionUID to implement version control.
1.1 Address.java
A serializable class with a serialVersionUID of 1L.
import java.io.Serializable;
public class Address implements Serializable{
private static final long serialVersionUID = 1L;
String street;
String country;
public void setStreet(String street){
this.street = street;
}
public void setCountry(String country){
this.country = country;
}
public String getStreet(){
return this.street;
}
public String getCountry(){
return this.country;
}
@Override
public String toString() {
return new StringBuffer(" Street : ")
.append(this.street)
.append(" Country : ")
.append(this.country).toString();
}
}
1.2 WriteObject.java
A simple class to write / serialize the Address object into a file – “c:\\address.ser”.
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class WriteObject{
public static void main (String args[]) {
Address address = new Address();
address.setStreet("wall street");
address.setCountry("united states");
try{
FileOutputStream fout = new FileOutputStream("c:\\address.ser");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(address);
oos.close();
System.out.println("Done");
}catch(Exception ex){
ex.printStackTrace();
}
}
}
1.3 ReadObject.java
A simple class to read / deserialize the Address object from file – “c:\\address.ser”.
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class ReadObject{
public static void main (String args[]) {
Address address;
try{
FileInputStream fin = new FileInputStream("c:\\address.ser");
ObjectInputStream ois = new ObjectInputStream(fin);
address = (Address) ois.readObject();
ois.close();
System.out.println(address);
}catch(Exception ex){
ex.printStackTrace();
}
}
}
2. Testing
Let do some testing to demonstrate the use of serialVersionUID.
2.1 Same serialVersionUID
Same serialVersionUID , there is no problem during the deserialization process
javac Address.java
javac WriteObject.java
javac ReadObject.java
java WriteObject
java ReadObject
Street : wall street Country : united states
2.2 Different serialVersionUID
In Address.java, change the serialVersionUID to 2L (it was 1L), and compile it again.
javac Address.java
java ReadObject
java.io.InvalidClassException: Address; local class incompatible:
stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
...
at ReadObject.main(ReadObject.java:14)
The “InvalidClassException” will raise, because you write a serialization class with serialVersionUID “1L” but try to retrieve it back with updated serialization class, serialVersionUID “2L”.
The serialVersionUID have to match during the serialization and deserialization process.
For detail about the compatible and incompatible Java type changes to a serializable class, see the Java Object Serialization Specification.
3. What’s wrong with the default serialVersionUID?
If no serialVersionUID is declared, JVM will use its own algorithm to generate a default SerialVersionUID, you can check the algorithm here.
The default serialVersionUID computation is highly sensitive to class details and may vary from different JVM implementation, and result in an unexpected InvalidClassExceptions during the deserialization process.
3.1 Client / Server environment
– Client is using SUN’s JVM in Windows. – Server is using JRockit in Linux.
The client sends a serializable class with default generated serialVersionUID (e.g 123L) to the server over socket, the server may generate a different serialVersionUID (e.g 124L) during deserialization process, and raises an unexpected InvalidClassExceptions.
3.2 File / Database environment
– App #1 is using SUN’s JVM in Windows. – App #2 is using JRockit in Linux.
Serialization has allowed to save into a file or database. App #1 stores a serializable class into database by default generated serialVersionUID (e.g 123L), while App #2 may generate a different serialVersionUID (e.g 124L) during deserialization process, and raise an unexpected InvalidClassExceptions.
You can check here for the List of the JVM implementation.
4. How to generate serialVersionUID
You can use JDK “serialver” or Eclipse IDE to generate serialVersionUID automatically, see detail.
Conclusion
SUN is highly recommended developers to declare the serialVersionUID in order to avoid the different JVM issue listed above, however I rather recommend you should understand what is serialization, how serialVersionUID implement version control and why your class need to use serialization. Understand the serialVersionUID concept is better than blindfold to any recommendation.
References
- http://en.wikipedia.org/wiki/List_of_JVM_implementations
- http://java.sun.com/javase/6/docs/platform/serialization/spec/class.html#4100
- http://stackoverflow.com/questions/419796/explicit-serialversionuid-considered-harmful
- http://en.wikipedia.org/wiki/Serialization#Java
- http://www.javaworld.com/javaworld/jw-02-2006/jw-0227-control.html?page=1
- http://www.javablogging.com/what-is-serialversionuid/
- http://java.dzone.com/articles/dont-ignore-serialversionuid
- http://www.java-forums.org/new-java/8196-serialversionuid.html
【转载】 http://www.mkyong.com/java-best-practices/understand-the-serialversionuid/
【转载】Understand the serialVersionUID的更多相关文章
- local class incompatible: stream classdesc serialVersionUID = -2897844985684768944, local class serialVersionUID = 7350468743759137184
local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2427 ...
- Java中serialVersionUID的解释及两种生成方式的区别(转载)
转载自:http://blog.csdn.net/xuanxiaochuan/article/details/25052057 serialVersionUID作用: 序列化时为了保持版 ...
- 转载:AbstractQueuedSynchronizer的介绍和原理分析
简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...
- JAVA中SERIALVERSIONUID的解释
serialVersionUID作用: 序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性.有两种生成方式: 一个是默认的1L,比如:private st ...
- [转载] Java高新技术第一篇:类加载器详解
本文转载自: http://blog.csdn.net/jiangwei0910410003/article/details/17733153 首先来了解一下字节码和class文件的区别: 我们知道, ...
- 【转载】Recommendations with Thompson Sampling (Part II)
[原文链接:http://engineering.richrelevance.com/recommendations-thompson-sampling/.] [本文链接:http://www.cnb ...
- 【转载】安卓APP架构
注:本篇博文转载于 http://my.oschina.net/mengshuai/blog/541314?fromerr=z8tDxWUH 本文介绍了文章作者从事了几年android应用的开发,经历 ...
- JavaWeb防止表单重复提交(转载)
转载自:http://blog.csdn.net/ye1992/article/details/42873219 在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用 ...
- Java序列化中的SerialVersionUid
版权声明:本文为博主fbysss原创文章,转载请注明出处 作者:fbysssmsn:jameslastchina@hotmail.com blog:blog.csdn.NET/fbysss声明:本文 ...
随机推荐
- Perl的基本语法(转)
(原文来自:http://www.jb51.net/shouce/perl.htm)
- 关于HTML页面布局要注意的问题
1.用百分比设定元素宽度可能造成的错误 很多同学习惯使用百分比来设定页面元素(例如div,以下称作盒子,方便介绍)的宽度,这样做可能造成未知的错误,最常见的就是当页面被缩小,或者屏幕分辨率降低时,由于 ...
- QML Image: Cannot open: qrc:///new.pic.png
初次遇到这个问题真有点摸不着头脑,于是乎百度一下咯,但是百度一向没有什么用,该有的没有,没用的回答倒是有特么一大堆. 自己解决: 我的解决方法很简答: 第一步:把图片放到当前路径下,也就是和.pro一 ...
- nagios监控系统安装及配置
Nagios通常由一个主程序(Nagios).一个插件程序(Nagios-plugins)和四个可选的ADDON(NRPE.NSCA.NSClient++和NDOUtils)组成.Ngios的监控工作 ...
- 继续OI
NOIP2016于2016.11.20日12:00正式结束. 我作为oi的生涯 或许会结束? 或者继续? 然而前途依然迷茫,我是否应该继?或是放弃? 距离省选还有3~4个月,我该何去何从? 虽然已经经 ...
- Window memcache 使用
一.memcache配置 1. 下载memcache 32位系统 1.2.5版本:http://static.runoob.com/download/memcached-1.2.5-win32-bin ...
- 【linux】 解决linux下vsftp 500 OOPS: cannot change directory:/home/ftp/ 办法
用FileZilla连接ftp出现错误,500 OOPS: cannot change directory:/home/ftp 原因是CentOS系统安装了SELinux,因为默认下是没有开启FTP的 ...
- 使用C#/.net语言进行ProE/Creo二次开发
随便哪个版本的Visual studio 设置系统环境变量 通常这个环境变量在安装ProE的时候如果选择安装VBAPI就会自动设置 注意32位和64位操作系统路径是不同的.我的是64位操作系统. 然后 ...
- myeclipse构建webservice项目
新建server端 1 创建Web Service Project项目 2.项目名称:HelloWorldServer 3.创建接口类 4.发布 选择项目名称,选择从Java类中构建web servi ...
- matlab global 不能传向量/矩阵
matlab global 不能传向量/矩阵 只能传1个数值 而函数变量可以传向量/矩阵