汗,以前学了还忘了。。。

Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。 

Eclipse中The serializable class XXXXXX does not declare a static final serialVersionUID field of type long出现这样的警告处理办法。 

当采用程序的Add default Serial version ID修复时,Eclipse会加上:private static final long serialVersionUID = 1L; 

当采用程序的Add generated Serial version ID修复时,Eclipse会加上:private static final long serialVersionUID = xxxxL; 

其实这个问题出现的具体原因是和序列化中的这个serialVersionUID有关。 

serialVersionUID 用来表明类的不同版本间的兼容性。有两种生成方式: 

一个是默认的1L,比如:private static final long serialVersionUID = 1L;(对应修复方法1) 

一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如: 
private static final long serialVersionUID = xxxxL;(对应修复方法2) 

在JDK中,可以利用JDK的bin目录下的serialver.exe工具产生这个serialVersionUID 的值,对于Test.class,执行命令: 
serialver Test   这时JVM(java虚拟机)会生成一个哈希字段。 

对比一下这个哈希字段的值与方法2中生成的字段值是一样的,可见,在CMD中使用serialver指令就是根据类名、接口名、成员方法及属性等来生成哈希字段的。 

下面来讨论java类中为什么需要重载 serialVersionUID 属性。 

当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。 

  把Java对象转换为字节序列的过程称为对象的序列化。 

  把字节序列恢复为Java对象的过程称为对象的反序列化。 

  对象的序列化主要有两种用途: 

  1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中; 

  2) 在网络上传送对象的字节序列。 

java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。 

java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。 

只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式 。 

凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:private static final long 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会重新编译程序,那些警告信息也就消失了。 

struts架构下的网站经常出现javax.servlet.ServletException: BeanUtils.populate 错误,但是本地运行又一切正常,唯一觉得可能产生问题的就是服务器上跑了好几个网站,都是一样的架构的,怀疑是不是web容器把几个项目之间的java类给共用了,考虑到很多类都定义了serialVersionUID字段,然后尝试删除了某个类的serialVersionUID,结果关于该类的操作就恢复正常了。网上简单查阅了一下资料,感觉是tomcat把所有类串行化时候,由于我们的几个项目很多java类都是复制粘贴的,所以导致了很多类的serialVersionUID都是同一个值,所以tomcat会把不同项目的相同类名的类当作同一个类去处理,导致了这个奇怪的错误。 

解决方案: 
每个项目同名的类serialVersionUID改为不一样,不能直接的复制粘贴过来。

参考:

http://blog.csdn.net/dancen/article/details/7236575

http://www.tuicool.com/articles/MFNFjq

错误: java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.example.administrator.amr_patient.tempbean.ModelGuidance)

这个问题的解决方法很简单,类和类的成员变量都要继承可序列化接口。

转:serialVersionUID作用的更多相关文章

  1. 【java】serialVersionUID作用

    serialVersionUID适用于Java的序列化机制.简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的.在进行反序列化时,JVM会把传来的字节流中的 ...

  2. serialVersionUID作用

    serialVersionUID适用于Java的序列化机制.简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的.在进行反序列化时,JVM会把传来的字节流中的 ...

  3. java类中serialversionuid 作用 是什么?举个例子说明(转)

    serialVersionUID适用于Java的序列化机制.简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的.在进行反序列化时,JVM会把传来的字节流中的 ...

  4. serialVersionUID作用是什么以及如何生成的?

    目录 正常不设置serialVersionUID 的序列化和反序列化 序列化之后,类文件增加了字段,反序列化会怎么样? 指定serialVersionUID,减少或者增加字段会发生什么? serial ...

  5. java类中serialversionuid 作用 是什么?举个例子说明

    serialVersionUID适用于Java的序列化机制.简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的.在进行反序列化时,JVM会把传来的字节流中的 ...

  6. Java serialVersionUID作用和生成

    序列化和反序列化Java是面向对象的语言,与其他语言进行交互(比如与前端js进行http通信),需要把对象转化成一种通用的格式比如json(前端显然不认识Java对象),从对象到json字符串的转换, ...

  7. 5. Java中序列化的serialVersionUID作用

    Java序列化是将一个对象编码成一个字节流,反序列化将字节流编码转换成一个对象. 序列化是Java中实现持久化存储的一种方法:为数据传输提供了线路级对象表示法. Java的序列化机制是通过在运行时判断 ...

  8. serialVersionUID 作用

    一个类在序列化时,用来记录当前类的版本号.在反序列化时,首先获取当前类的版本号,不一致则报异常. 若版本号一致,但两个类不一致.写肯定全部写进去.但提取时 类若没有这个字段,则不提取.若提取类多个字段 ...

  9. serialVersionUID的作用以及设置方法(转)

    声明:本篇文章是转载的 http://blog.csdn.net/kakaxi_77/article/details/8129070 http://snowlotus.iteye.com/blog/2 ...

随机推荐

  1. CoreCRM 开发实录 —— Profile

    再简单的功能,也需要一坨代码的支持.Profile 的编辑功能主要就是修改个人的信息.比如用户名.头像.性别.电话--虽然只是一个编辑界面,但添加下来,涉及了6个文件的修改和7个新创建的文件.各种生成 ...

  2. 透过WinDBG的视角看String

    摘要 : 最近在博客园里面看到有人在讨论 C# String的一些特性. 大部分情况下是从CODING的角度来讨论String. 本人觉得非常好奇, 在运行时态, String是如何与这些特性联系上的 ...

  3. .Net多线程编程—任务Task

    1 System.Threading.Tasks.Task简介 一个Task表示一个异步操作,Task的创建和执行是独立的. 只读属性: 返回值 名称 说明 object AsyncState 表示在 ...

  4. C# 条形码操作【源码下载】

    本篇介绍通过C#生成和读取一维码.二维码的操作. 目录 1. 介绍:介绍条形码.条形码的分类以及ZXing.Net类库. 2. 一维码操作:包含对一维码的生成.读取操作. 3. 二维码操作:包含对二维 ...

  5. 用html5的canvas和JavaScript创建一个绘图程序

    本文将引导你使用canvas和JavaScript创建一个简单的绘图程序. 创建canvas元素 首先准备容器Canvas元素,接下来所有的事情都会在JavaScript里面. <canvas ...

  6. iOS开发之Masonry框架源码深度解析

    Masonry是iOS在控件布局中经常使用的一个轻量级框架,Masonry让NSLayoutConstraint使用起来更为简洁.Masonry简化了NSLayoutConstraint的使用方式,让 ...

  7. 步入angularjs directive(指令)--准备工作熟悉hasOwnProperty

    在讲解directive之前,先做一下准备工作,为何要这样呢? 因为我们不是简单的说说directive怎么用,还要知道为什么这么用!(今天我们先磨磨刀!). 首先我们讲讲js 基础的知识--hasO ...

  8. 代码的坏味道(19)——狎昵关系(Inappropriate Intimacy)

    坏味道--狎昵关系(Inappropriate Intimacy) 特征 一个类大量使用另一个类的内部字段和方法. 问题原因 类和类之间应该尽量少的感知彼此(减少耦合).这样的类更容易维护和复用. 解 ...

  9. Node.js使用PM2的集群将变得更加容易

    介绍 众所周知,Node.js运行在Chrome的JavaScript运行时平台上,我们把该平台优雅地称之为V8引擎.不论是V8引擎,还是之后的Node.js,都是以单线程的方式运行的,因此,在多核心 ...

  10. Salesforce开发者学习笔记之一:基本知识

    本文介绍了Salesforce开发平台的基本知识, 包括如下内容: Salesforce平台介绍 Salesforce基本术语 定制和扩展Salesforce平台 创建一个简单的应用程序 Salesf ...