关于Serializable的serialVersionUID

在实现了Serializable接口的class中,需要声明一个long serialVersionUID,用来标明当前class的版本号,但很多人在编程时,总是不原意去声明这个serialVersionUID,又JVM自己来生成。下面来看看serialVersionUID的作用:

1、如果在序列化写 时的版本号和序列化读 时的版本号,不一致,将会有异常:java.io.InvalidClassException:local class incompatible: stream classdesc serialVersionUID = …, local class serialVersionUID = …

2、那如果在class中不声明这个属性呢?那结果可以就会变得比较诡异了:

1)、在序列化写 的时候,虚拟机A会为它计算出一个serialVersionUID,计算的方法是依据class的信息,再具体我也不清楚了。

2)、在序列化读 的时候,虚拟机B也会为class计算出一个serialVersionUID,然后做比较。

3)、那么如果两个虚拟机是不同类型的虚拟机,那么计算方法可能就不一样了,于是即使相同的class,serialVersionUID也可能会不同,不同的class的,理论上来说,也存在serialVersionUID相同的可能性,所以,serialVersionUID尽量由我们自己来指定,而不要由虚拟机来计算。

3、那如果serialVersionUID一致,而class发生了变化呢?

1)、如果虚拟机A中的AClass有一个属性,而虚拟机B中的AClass,没有这个属性,那么这个属性将被忽略,而不会有异常。

2)、如果虚拟机A中的AClass没有的属性,而在虚拟机B中多出来的属性,那么这个属性将被赋予一个缺省值,而不会有异常。

3)、如果虚拟机A中的AClass有一个属性,在虚拟机B中的AClass也有这个属性,但这个属性的类型变了,比如说int变成了long,抑或其他的变化,将会有异常:java.io.InvalidClassException:incompatible types for field …

经过序列化而产生的异常都是 java.io.InvalidClassException,不会产生java.lang.ClassCastException,两者还是有比较大的区别的,从名字上就可以看得出来。

看完你还会让JVM自己来生成serialVersionUID吗?你还加@SuppressWarnings("serial")吗?在一个单机上或许看不出什么问题,但在分布式计算、或者你需要提供jar供别人使用的时候,这个问题就会暴露。

时间: 2024-08-24 06:59:58

关于Serializable的serialVersionUID的相关文章

Serializable and serialVersionUID

如果某个 class implements Serializable,Eclipse 会提示生成 serialVersionUID ,多数情况下,我都选择是.可这个东西到底是什么呢? package com.home.demo; import java.io.Serializable; public class Item implements Serializable { private static final long serialVersionUID = 1L; private int d

java.io.Serializable中serialVersionUID的作用

把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中: 2) 在网络上传送对象的字节序列. 在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存.比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中

Serializable资料整理

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "PingFang SC" } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "PingFang SC"; min-height: 17.0px } span.s1 { font: 12.0px Helvetica } 1. 序列化 简单的说就是为了保存 内存中各种对象的状态(是实例变量,不是方法),并

Arrays源码分析

package java.util; import java.lang.reflect.Array; import java.util.concurrent.ForkJoinPool; import java.util.function.BinaryOperator; import java.util.function.Consumer; import java.util.function.DoubleBinaryOperator; import java.util.function.IntBi

[ 转 ]编写高质量代码:改善Java程序的151个建议

记得3年前刚到公司,同桌同事见我无事可做就借我看<编写高质量代码:改善Java程序的151个建议>这本书,当时看了几页没上心就没研究了.到上个月在公司偶然看到,于是乎又找来看看,我的天,真是非常多的干货,对于我这种静不下心的人真是帮助莫大呀. 看完整本书,也记了不少笔记,我就分享一部分个人觉得有意义的内容,也为了方便以后自己温习. --警惕自增陷阱 i++表示先赋值后自增,而++i表示先自增后赋值.下面的代码返回结果为0,因为lastAdd++有返回值,而返回值是自增前的值(在自增前变量的原始

JSON字符串转JavaBean,net.sf.ezmorph.bean.MorphDynaBean cannot be cast to ……

在json字符串转java bean时,一般的对象,可以直接转,如:一个学生类,属性有姓名.年龄等 public class Student implements java.io.Serializable{ /** * @Fields serialVersionUID : TODO */ private static final long serialVersionUID = -1943961352036134112L; private String sname; private Integer

学生管理系统----学生封装类

Student.java: /** * @Title:Student.java * @Package:com.you.student.system.model * @Description:学生信息封装类 * @author:Youhaidong(游海东) * @date:2014-6-16 下午11:00:22 * @version V1.0 */ package com.you.student.system.model; import java.io.Serializable; import

SpringBoot实践 - SpringBoot+mysql

关于springBoot是个神马东西以及优缺点,请自行搜索了解. LZ看到很多关于SpringBoot的Demo,单看一篇总是没法整合SpringBoot与Mysql.没法子,还是自己操刀来一发为妙. 本文将叙述关于SpringBoot与mysql整合实践. 1.Eclipse 整合SpringBoot插件.(此步骤非常耗时,LZ本身尝试了多次.请在网络环境优情况下下进行操作) a.Eclipse 安装STS插件: eclipse->help->Eclipse Marketplace b.检测

JdkDynamicAopProxy源码

JdkDynamicAopProxy是通过接口实现动态代理类,主要方法是getProxy(ClassLoader classLoader), 代理类生成之后再调用目标方法时就会调用invoke方法. package org.springframework.aop.framework; import java.io.Serializable; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; i