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.

When should update your serialVersionUID? When your serialization class is updated with some incompatible Java type changes to a serializable class, you have to update your serialVersionUID.

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

  1. http://en.wikipedia.org/wiki/List_of_JVM_implementations
  2. http://java.sun.com/javase/6/docs/platform/serialization/spec/class.html#4100
  3. http://stackoverflow.com/questions/419796/explicit-serialversionuid-considered-harmful
  4. http://en.wikipedia.org/wiki/Serialization#Java
  5. http://www.javaworld.com/javaworld/jw-02-2006/jw-0227-control.html?page=1
  6. http://www.javablogging.com/what-is-serialversionuid/
  7. http://java.dzone.com/articles/dont-ignore-serialversionuid
  8. http://www.java-forums.org/new-java/8196-serialversionuid.html

【转载】 http://www.mkyong.com/java-best-practices/understand-the-serialversionuid/

【转载】Understand the serialVersionUID的更多相关文章

  1. local class incompatible: stream classdesc serialVersionUID = -2897844985684768944, local class serialVersionUID = 7350468743759137184

    local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2427 ...

  2. Java中serialVersionUID的解释及两种生成方式的区别(转载)

    转载自:http://blog.csdn.net/xuanxiaochuan/article/details/25052057 serialVersionUID作用:        序列化时为了保持版 ...

  3. 转载:AbstractQueuedSynchronizer的介绍和原理分析

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  4. JAVA中SERIALVERSIONUID的解释

    serialVersionUID作用:        序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性.有两种生成方式:       一个是默认的1L,比如:private st ...

  5. [转载] Java高新技术第一篇:类加载器详解

    本文转载自: http://blog.csdn.net/jiangwei0910410003/article/details/17733153 首先来了解一下字节码和class文件的区别: 我们知道, ...

  6. 【转载】Recommendations with Thompson Sampling (Part II)

    [原文链接:http://engineering.richrelevance.com/recommendations-thompson-sampling/.] [本文链接:http://www.cnb ...

  7. 【转载】安卓APP架构

    注:本篇博文转载于 http://my.oschina.net/mengshuai/blog/541314?fromerr=z8tDxWUH 本文介绍了文章作者从事了几年android应用的开发,经历 ...

  8. JavaWeb防止表单重复提交(转载)

    转载自:http://blog.csdn.net/ye1992/article/details/42873219 在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用 ...

  9. Java序列化中的SerialVersionUid

    版权声明:本文为博主fbysss原创文章,转载请注明出处 作者:fbysssmsn:jameslastchina@hotmail.com  blog:blog.csdn.NET/fbysss声明:本文 ...

随机推荐

  1. 小米note3,华为手机,软键盘弹出之后,页面上定位的元素布局会乱掉

    原因:可能是因为,软键盘弹出时,改变了height,使height:100%,不能达到原来的高度. 解决办法: $(document).ready(function () { $('body').he ...

  2. xmind的第十二天笔记

  3. 2016年中国大学生程序设计竞赛(合肥)-重现赛1008 HDU 5968

    异或密码 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submis ...

  4. ng-class的用法

    最近在学习angular框架,ng-class是angular框架的一个指令,这里是ng-class指令的官方解释: ng-class 指令用于给 HTML 元素动态绑定一个或多个 CSS 类. ng ...

  5. C++ STL泛型编程——在ACM中的运用

    学习过C++的朋友们应该对STL和泛型编程这两个名词不会陌生.两者之间的关系不言而喻,泛型编程的思想促使了STL的诞生,而STL则很好地体现了泛型编程这种思想.这次想简单说一下STL在ACM中的一些应 ...

  6. JSP代码加固

    String id = request.getParameter("id"); String id = id.replace("'","") ...

  7. SpringMVC,3种不同的URL路由配置方法

    1. 先说说一种比较常见的: <servlet> <servlet-name>theDispatcher</servlet-name> <servlet-cl ...

  8. Linear Algebra lecture1 note

    Professor: Gilbert Strang Text: Introduction to Linear Algebra http://web.mit.edu/18.06   Lecture 1 ...

  9. VMware Player安装Debian系统

    尝试用虚拟机来安装Debian系统,感觉这样一来安装与卸载方便,二来也可以在Linux系统安装出现问题的情况下方便在host主机上查找解决方法,同时也避免了要重新设置分区来安装Linux系统(双系统的 ...

  10. error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用

    MSVCRTD.lib(crtexew.obj) : error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用 Debug ...