`
leonzhx
  • 浏览: 794154 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Understand the serialVersionUID

    博客分类:
  • Java
阅读更多

If you 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 did it for you automatically, based on various aspects of your Serializable class, as describe in the Java(TM) Object Serialization Specification .

SerialVersionUID Example

The above statement is a bit hard to understand at the beginning (as least i did), let start an example to understand how Serializable class use SerialVersionUID to implement version control.

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();
	   }
}

 

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 state");
 
	   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();
	   } 
	}
}

 

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(); 
	   } 
   }
}

 

Testing

Let do some testing to demonstrate the use of serialVersionUID.

1. Same serialVersionUID

Same serialVersionUID , there are no problem during deserialization process

javac Address.java
javac WriteObject.java
javac ReadObject.java
java WriteObject
java ReadObject
Street : wall
 street Country : united state

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 by 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.

What’s wrong with the default serialVersionUID?

If no serialVersionUID is declare, JVM will used 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 deserialization process.

1. Client / Server environment

- Client is using SUN’s JVM in Windows.
- Server is using JRockit in Linux.

Client sends a serializable class with default generated serialVersionUID (e.g 123L) to server over socket, server may generate a different serialVersionUID (e.g 124L) during deserialization process, and raise an unexpected InvalidClassExceptions.

2. File / Database environment

- App #1 is using SUN’s JVM in Windows.
- App #2 is using JRockit in Linux.

Serialization is allow to save into a file or database. App #1 stores a serializable class into database with 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 .

How to generate serialVersionUID

You can use JDK “serialver” or Eclipse IDE to generate serialVersionUID automatically, see detail .

Conclusion

SUN is highly recommends 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.

Reference

  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

This article originates from http://www.mkyong.com/java-best-practices/understand-the-serialversionuid/

分享到:
评论

相关推荐

    Java中serialVersionUID的解释

    Java 中 serialVersionUID 的解释 Java 中的 serialVersionUID 是一个非常重要的概念,在实现 Serializable 接口的类中,它扮演着至关重要的角色。那么,serialVersionUID到底是什么?它又是如何生成的?在本篇文章...

    详述IntelliJ IDEA 中自动生成 serialVersionUID 的方法(图文)

    IntelliJ IDEA 自动生成 serialVersionUID 在 Java 序列化机制中,serialVersionUID 是一个不可或缺的角色,它可以通过在运行时判断类的 serialVersionUID 来验证版本一致性。在进行反序列化时,JVM 会把传来的字节...

    coreJava: serialVersionUID

    在Java编程中,`serialVersionUID` 是一个非常重要的概念,特别是在序列化和反序列化过程中。这个特殊标识符主要用于版本控制,确保不同版本的类在序列化和反序列化时能够正确匹配。当我们讨论`serialVersionUID`时...

    java类中serialVersionUID详解.pdf

    ### Java 类中 `serialVersionUID` 详解 #### 一、`serialVersionUID` 概述 在 Java 中,`serialVersionUID` 是一个与类关联的长整型常量,用于支持序列化机制。当一个对象被序列化时,该对象所属类的 `...

    serialVersionUID作用全面解析

    serialVersionUID 作用全面解析 serialVersionUID 是 Java 序列化机制中一个非常重要的概念,它是 Java 序列化机制的核心组件。 serialVersionUID 是一个长整型常量,用于标识类的版本号。在 Java 序列化机制中,...

    serialVersionUID.txt

    三期第一张IO笔记 6

    idea如何自动生成serialVersionUID

    "IDEA如何自动生成serialVersionUID" IDEA中自动生成serialVersionUID是Java开发中的一项重要功能,因为serialVersionUID是一个非常重要的字段,用于验证类的版本一致性。在本文中,我们将详细介绍如何使用IDEA自动...

    java类中serialVersionUID的作用及其使用

    Java类中serialVersionUID的作用及其使用 Java类中serialVersionUID是一种特殊的静态变量,用于标识类的序列化版本。它是Java语言中实现Serializable接口的类必须定义的变量,用于在反序列化时验证类的版本一致性。...

    全面解释Java中的serialVersionUID

    Java中的`serialVersionUID`是一个非常重要的概念,尤其是在处理序列化和反序列化操作时。序列化是将对象的状态转换为字节流的过程,而反序列化则是将字节流恢复为对象状态。`serialVersionUID`的主要作用是确保在类...

    614.612.JAVA基础教程_IO流与网络编程-serialVersionUID的理解(614).rar

    本教程将深入探讨这两个主题,并特别关注`serialVersionUID`这个概念。`serialVersionUID`在Java序列化过程中起着关键作用。 首先,让我们来理解什么是IO流。IO流是Java中处理数据输入和输出的一种机制。Java提供了...

    java序列化和serialVersionUID的使用方法实例

    Java 序列化和 serialVersionUID 的使用方法实例 Java 序列化是指将 Java 对象转换为二进制流的过程,以便在网络中传输或持久化到数据库或文件系统中。序列化的作用是将 Java 对象的状态保存起来,以便下次使用时...

    序列化版本号serialVersionUID的作用_动力节点Java学院整理

    序列化版本号serialVersionUID的作用_动力节点Java学院整理.

    Java自定义异常案例--ExceptionManager(java源码)

    private static final long serialVersionUID = -6963187366089365790L; /** * This field <code>alerter</code> is used to show the information the Class offered. * * @see javax.swing.JOptionPane ...

    反序列化失败的原因报告

    系统会根据类的修饰符、实现的接口、定义的方法以及属性等信息计算出 serialVersionUID,因而导致本地的实体类和服务器上的实体类的 serialVersionUID 不一致。 解决方案 解决反序列化失败的解决方案是给相关实体...

    使用自定义ClassLoader解决反序列化serialVesionUID不一致问题 _ 回忆飘如雪1

    此方法能解决所有类的`serialVersionUID`问题,但如果类的属性类型发生变化,仅修改`serialVersionUID`是不够的,因为`serialVersionUID`的变更不仅与类的标识有关,还与类的属性和方法相关。 5. **使用`...

    java.io.InvalidClassException local class incompatible 处理方法

    如果序列化类没有显式声明`serialVersionUID`,则序列化运行时将根据类的各种细节自动计算一个默认的`serialVersionUID`值。然而,这种默认的计算方式对类的细节非常敏感,并且可能因不同的Java编译器实现而异,从而...

    GenerateSerialVersionUID

    而`Serializable`接口是Java实现序列化的主要方式,其中`serialVersionUID`字段对于序列化过程至关重要。`GenerateSerialVersionUID`插件则是针对这个特殊需求开发的工具,帮助开发者自动为类生成`serialVersionUID`...

    Servlet查询数据库案例--Query(java源码)

    private static final long serialVersionUID = -5616899811848789885L; Connection db; // This is the shared JDBC database connection public void init() throws ServletException { // Read ...

Global site tag (gtag.js) - Google Analytics