Q:java中serialVersionUID的作用

idea如何自动生成serialVersionUID 主要介绍了idea如何自动生成serialVersionUID,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 立即下载

@转载自:http://www.cnblogs.com/guanghuiqq/archive/2012/07/18/2597036.html

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

serialVersionUID有两种显示的生成方式:
1.一个是默认的1L,比如:private static final long serialVersionUID = 1L;

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

当你一个类实现了Serializable接口,如果没有显示的定义serialVersionUID,Eclipse会提供提示功能告诉你去定义 。在Eclipse中点击类中warning的图标一下,Eclipse就会 自动给定两种生成的方式。如果不想定义它,在Eclipse的设置中也 可以把它关掉的。

设置如下: Window ==> Preferences ==> Java ==> Compiler ==> Error/Warnings ==> Potential programming problems 将Serializable class without serialVersionUID的warning改成ignore即可。

当实现java.io.Serializable接口的实体(类)没有显式地定义一个名为serialVersionUID,类型为long的变量时,Java序列化机制会根据编译的class(它通过类名,方法名等诸多因素经过计算而得,理论上是一一映射的关系,也就是唯一的)自动生成一个serialVersionUID作序列化版本用于比较用,这种情况下,如果class文件(类名,方法明等)没有发生变化(增加空格,换行,增加注释,等等),就算再编译多次,serialVersionUID也不会变化的,但是一旦源java文件发生了一丁点变化,在进行重新进行编译后所生成的class文件中,其serialVersionUID会发生改变,从而会导致反序列化的失败。如果我们不希望通过编译来强制划分软件版本,即实现序列化接口的实体能够兼容先前版本,未作更改的类,就需要显式地定义一个名为serialVersionUID,类型为long的变量,不修改这个变量值的序列化实体都可以相互进行串行化和反串行化。

如果你没有考虑到兼容性问题时,就把它关掉,不过有这个功能是好的,只要任何类别实现了Serializable这个接口的话,如果没有加入 serialVersionUID,Eclipse都会给你warning提示,这个serialVersionUID为了让该类别 Serializable向后兼容。

问题一:假设有A端和B端,如果2处的serialVersionUID不一致,会产生什么错误呢?

问题二:假设2处serialVersionUID一致,如果A端增加一个字段,B端不变,会是什么情况呢?

问题三:假设2处serialVersionUID一致,如果B段增加一个字段,A端不变,会是什么情况呢?

问题四:假设2处serialVersionUID一致,如果A端减少一个字段,B端不变,会是什么情况呢?

问题五:假设2处serialVersionUID一致,如果B端减少一个字段,A端不变,会是什么情况呢?

例子如下:写2个类,类名相同,字段相同,方法相同.放在不同的包里,来模仿A端和B端.

实体类:在本例中,在测试类SerialTest执行前代表A端,然后,在测试类DeserialTest执行前代表B端.

package com.test; import java.io.Serializable;

public class Serial implements Serializable
{
 private static final long serialVersionUID = 6977402643848374753L;
 int id;
 String name;
 public Serial(int id, String name)
 {
  this.id = id;
  this.name = name;
 }
 public String toString()
 {
  return “DATA: ” + id + ” ” +name;
 }
}

测试类,代表A端的序列化

package com.test.serializable;

import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream;

public class SerialTest
{

/* @param args */
 public static void main(String[] args)
 { // TODO Auto-generated method stub
  Serial serial1 = new Serial(1,”song”);   System.out.println(“Object Serial”+serial1);
  try
  {
   FileOutputStream fos = new FileOutputStream(“serialTest.txt”);
   ObjectOutputStream oos = new ObjectOutputStream(fos);
   oos.writeObject(serial1);
   oos.flush();
   oos.close();
  }
  catch (FileNotFoundException e)
  { // TODO Auto-generated catch block
   e.printStackTrace();
   }
  catch (IOException e)
  { // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}

测试类,代表B端的反序列化

package com.test.serializable;

import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.ObjectInputStream;

public class DeserialTest
{
 public static void main(String[] args)
 {
  Serial serial2;
  try
  {
   FileInputStream fis = new FileInputStream(“H://serialTest.txt”);
   ObjectInputStream ois = new ObjectInputStream(fis);
   serial2 = (Serial) ois.readObject();
   ois.close();
   System.out.println(“Object Deserial” + serial2);
   System.out.println(“B also is OK!”);
  }
  catch (FileNotFoundException e)
  {
   e.printStackTrace();
  }
  catch (IOException e)
  {
   e.printStackTrace();
  }
  catch (ClassNotFoundException e)
  {
   e.printStackTrace();
  }
 }
}

问题一:假设有A端和B端,如果2处的serialVersionUID不一致,会产生什么错误呢?

答案如下:

1)先执行测试类SerialTest,然后修改serialVersion值(或注释掉serialVersion并编译),再执行测试类DeserialTest,报错:

java.io.InvalidClassException: com.test.serializable.Serial; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 11

2)A端和B端都没显示的写serialVersionUID,实体类没有改动(如果class文件(类名,方法明等)没有发生变化(增加空格,换行,增加注释,等等),).序列化,反序列化正常.

问题二:假设2处serialVersionUID一致,如果A端增加一个字段,B端不变,会是什么情况呢?

答案二: 序列化,反序列化正常,A端增加的字段丢失(被B端忽略).

问题五:假设2处serialVersionUID一致,如果B端减少一个字段,A端不变,会是什么情况呢?

答案:与问题二类似,序列化,反序列化正常,B端字段少于A端,A端多的字段值丢失(被B端忽略).

问题三:假设2处serialVersionUID一致,如果B段增加一个字段,A端不变,会是什么情况呢?

问题四:假设2处serialVersionUID一致,如果A端减少一个字段,B端不变,会是什么情况呢?(与问题三类似,四答案:序列化,反序列化正常,B端字段多余A端,B端多出的字段被赋予对应类型的默认值)

答案三: 序列化,反序列化正常,B端新增加的int字段被赋予了默认值0.

例子如下:

3)先执行SerialTest,然后在实体类增加一个字段age,再执行测试类DeserialTest.

package com.test.serializable;

import java.io.Serializable;

public class Serial implements Serializable
{
 private static final long serialVersionUID = -2337937881709830076L;

//private static final long serialVersionUID = 1L;
 int id;
 String name;
 public Serial(int id, String name)
 {
  this.id = id;
  this.name = name;
 }
 public String toString()
 {
  return “DATA: ” + id + ” ” +name;
 }
 public int age ;//在B端增加一个新字段
}

相应的修改测试类DeserialTest,打印出age的值.

package com.test.serializable;

import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.ObjectInputStream;

public class DeserialTest
{
/* @param args */
 public static void main(String[] args)
  { // TODO Auto-generated method stub
  Serial serial2 ;
  try
  {
   FileInputStream fis = new FileInputStream(“serialTest.txt”);
   ObjectInputStream ois = new ObjectInputStream(fis);
   serial2 = (Serial)ois.readObject();
   ois.close();
   System.out.println(“Object Deserial”+serial2+” age=”+serial2.age);
  }
  catch (FileNotFoundException e)
  { // TODO Auto-generated catch block
   e.printStackTrace();
  }
  catch (IOException e)
  { // TODO Auto-generated catch block
   e.printStackTrace();
   }
 }
}

打印结果如下:

Object DeserialDATA: 1 song age=0

说明序列化,反序列化正常,B端新增加的int字段被赋予了默认值0.

上面的情况对增加/减少 字段/方法 都适用.

//但当serialVersionUID相同时,它就会将不一样的field以type的预设值Deserialize,可避开不兼容性问题。

华为OD机试真题2025双机位C卷 Java&Go 实现【卡牌游戏】 小明正在尝试一种新的牌游戏。游戏规则只如下:首先,小明拿到一张写有数字m的牌。 然后,他会拿到另外n张牌,上面分别写有不同的数字,牌排成一排。小明的目标是从这排牌中找到一串连续的牌,这些牌上数字的总和可以被 m整除。你的任务是判断小明是否可以完成这个目标。 阅读详情

相关推荐

电力工程师必看:GOOSE/SV/MMS三协议在智能变电站中的分工与联动实例

本文深入解析了智能变电站中GOOSE、SV、MMS三大核心通信协议的分工与协同机制。GOOSE协议作为过程层的“闪电信使”,负责毫秒级传输跳闸命令等事件信息;SV协议则传输精确同步的电流电压采样值流;而MMS协议作为站控层的“管理语言”,实现设备监控与数据管理。三者基于IEC 61850标准,在过程层、间隔层和站控层之间高效联动,共同构建了智能变电站稳定可靠的通信骨架。

jj890的博客 369

java.beans.IntrospectionException: Method not found: isSerialVersionUID

求这个错误的解决办法: java.beans.IntrospectionException: Method not found: isSerialVersionUID at java.beans.PropertyDescriptor.<init>(PropertyDescriptor.java:107) at java.beans.PropertyDescriptor.<init>(PropertyDescriptor.java:71) at com.sin...

渣渣的成长之路 5846

QMT量化交易桥接方案深度对比:从MiniQMT淘汰说起

量化交易系统中的API桥接,本质是解决本地终端与底层交易引擎之间的通信瓶颈。其核心原理在于绕过GUI封装、直连确定性执行层,从而获得低延迟、高可靠、可监控的指令通路。技术价值体现在策略实盘一致性提升、毫秒级响应保障及运维可控性增强。典型应用场景包括打板策略、T+0套利、高频网格等对时效与稳定性双敏感的自动化交易。本文聚焦国金证券QMT专业版生态,系统剖析DLL注入、HTTP反向代理、IPC共享内存与官方HTTP API四大桥接路径的性能边界、合规风险与工程落地成本,尤其深入解析qmt终端 client is

weixin_33892359的博客 457

JAVA利用反射比较两个对象的属性值是否相等,可用于单据的变更比较,记录变更日志信息

JAVA利用反射比较两个对象的属性值是否相等 java代码 public static void main(String[] args) { Announcement announcement = new Announcement(); announcement.setContent("123"); announcement.setPhoto("测试"); Announcement announcement2 = new Announcement(); announcement2.set

weixin_44315761的博客 919

游戏大厂技术护城河——为什么你抄不了原神?

│ │ │ │ ↓ 通过 │ │ │ │。│ │ │ │ ↓ 成功 │ │ │ │。│ │ │ │ ↓ 完成 │ │ │ │。│ │ │ │ ↓ 达标 │ │ │ │。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 71

【微服务】Java 对接飞书多维表格使用详解

Java 对接飞书多维表格使用详解

congge_study的博客 1万+

JAVA学习序列化serialVersionUID错误

如果可序列化类未显式声明serialVersionUID,则序列化运行时将serialVersionUID基于类的各个方面计算该类的默认值,如Java(TM)对象序列化规范中所述。但是,强烈建议所有可序列化类显式声明serialVersionUID值,因为默认serialVersionUID计算对类详细信息高度敏感,可能因编译器实现而异,因此InvalidClassExceptions在反...

weixin_43256059的博客 1184

Altium Designer(AD24/25)PCB编辑的几种方法介绍

本文介绍了Altium Designer(AD24/25)软件中PCB编辑的四种操作方法:1)通过菜单栏"Place→Component"激活;2)点击工具栏元器件图标;3)右键快捷菜单选择;4)快捷键P+C组合操作。建议初学者先通过菜单栏和快捷菜单熟悉操作,熟练后转为工具栏和快捷键以提高效率。文章配有操作示意图,帮助用户快速掌握PCB元器件放置技巧。

fydar的博客 946

序列化和反序列化中serialVersionUID的作用

1、基本概念 把对象转换为字节序列的过程称为对象的序列化 把字节序列恢复为对象的过程称为对象的反序列化。 2、主要用途: 对象的序列化主要有两种用途:   1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;   2) 在网络上传送对象的字节序列。 /** * MethodName: SerializeCustomer * Description: 序列化Cu

2320

SAP_SD模块-销售批次策略应用记录

SAP_SD模块-销售批次策略完整案例

风沙的博客 2611

Unity GameObject 核心机制深度解析:从底层结构到工程实践

从底层机制讲透 Unity GameObject:托管壳加原生芯的双层对象模型如何制造假 null 陷阱、Transform 层级与组件通信的原理、生命周期回调的确切顺序。文章同时给出 Instantiate 成本分析与对象池等高频场景的工程实践。

游戏人生 40

java实体类中的序列化 和serialVersionUID

是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。

qq_39187593的博客 1950

Vision 机器视觉案例 之 零件边缘缺陷检测

缺陷检测工具

机器视觉李小白的博客 1387

idea 添加serialVersionUID提示

idea添加 serialVersionUID提示

寂夜了无痕的博客 5007

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

idea自动生成serialVersionUID

只需要在idea中简单配置下就可以自动生成serialVersionUID了如图配置位置 settings--&gt;Editor--&gt;Inspections 在输入框中入serialVersionUID找到在后面框框打钩就可以了...

寂夜了无痕的博客 431

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

什么是serialVersionUID,为什么我应该使用它?

在反序列化期间用于验证序列化对象的发送者和接收者是否已为该对象加载了与序列化相关的兼容类。如果接收者为该对象加载了一个与发送者的类具有不同的。可序列化的类 Foo 没有声明一个类型为 long 的静态最终 serialVersionUID 字段。计算对可能因编译器实现而有所不同的类细节非常敏感,并可能在反序列化期间导致意外的。序列化运行时会为每个可序列化的类分配一个版本号,称为。,该字段必须是静态的、最终的,并且类型为。值,一个可序列化的类必须声明一个显式的。一个可序列化的类可以通过声明一个名为。

m0_62946064的博客 189

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

关于Bean的知识private static final long serialVersionUID = 1L

实现java.io.Serializable这个接口是为序列化,serialVersionUID 用来表明实现序列化类的不同版本间的兼容性。如果你修改了此类, 要修改此值。否则以前用老版本的类序列化的类恢复时会出错。 实现后如果你用的是工具的话会出来警告,他会提示你,可以自动生成private static final long serialVersionUID = 1L; 为了在

lijie815917的专栏 524

Java序列化技术深度解析与面试必备

序列化是将对象转换为字节流的过程,在分布式系统、网络通信和数据存储等场景中至关重要。Java通过Serializable接口实现默认序列化,但存在性能、安全和兼容性等挑战。主流方案如JSON、Protobuf各有优劣,JSON易读但性能较低,Protobuf高效但需预定义Schema。反序列化漏洞如Fastjson和Shiro的安全问题也需重点关注。掌握序列化原理和最佳实践,能有效提升系统性能和安全性,是Java工程师面试和实际开发中的核心技能。

weixin_34007020的博客 348

319 序列化流中的3个问题,serialVersionUID & transient

319序列化流中的3个问题,serialVersionUID & transient (myOtherStream) Q1:用对象序列化流 序列化了 一个对象后,假如相关文件被修改,读数据会出问题吗? 例如,输出文件后,修改类的代码,添加一个toString方法。 会。java.io.InvalidClassException ObjectStreamExceptionSerialization运行时检测到类的以下问题之一时抛.

m0_63673788的博客 308

Java IO流(1)

Java IO流是处理数据输入输出的核心机制,主要分为字节流和字符流两大类。字节流(InputStream/OutputStream)操作8位字节,适用于所有数据类型;字符流(Reader/Writer)操作16位字符,专为文本设计,能正确处理中文等字符。流按功能可分为节点流(直接连接数据源)和处理流(包装增强功能,如缓冲流BufferedInputStream)。文件复制等操作应使用缓冲区提升性能,字符流能避免字节流处理中文时的乱码问题。关键点包括:区分读写方向、理解缓冲机制、掌

2301_78547133的博客 211

序列化深入浅出 —— Java版本

文章目录一、概念&作用二、Java实现序列化1.字节流序列化2.JSON序列化3.二者区别三、序列化安全1.serialVersionUID2.反序列化不安全 参看: 《深入理解序列化与反序列化》牛晓丽 https://www.bilibili.com/video/BV1E7411q7QK https://tech.meituan.com/2015/02/26/serialization-vs-deserialization.html 一、概念&作用 将本地已经实例化的某个对象(此

彭_德华的博客 469

Java入门到精通-25 IO流高级操作——序列化、NIO与Files工具类

本文介绍了Java高级IO操作中的序列化、NIO与Files工具类。主要内容包括: 序列化与反序列化:通过Serializable接口实现对象序列化,使用transient关键字控制序列化字段,强调serialVersionUID版本控制的重要性,并展示了集合的序列化操作。 NIO基础:对比传统IO与NIO的特性差异,详细讲解Buffer缓冲区的使用(包括position、limit、capacity等核心概念),以及文件通道(FileChannel)的读写操作。 关键特性: 序列化版本控制机制 NIO的非

weixin_56693899的博客 215

java常见面试考点(四十二):序列化与反序列化

java常见面试考点 往期文章推荐:   java常见面试考点(三十七):面向对象的三大特性   java常见面试考点(三十八):hashcode与equals   java常见面试考点(三十九):Math.round()方法   java常见面试考点(四十):try-catch-finally   java常见面试考点(四十一):short运算小错误 【版权申明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权); 本博客的内容来自于:; 学习、合作与交流联系q384660495; 本博客的内

qq_44159782的博客 499

【IDEA】最全总结100篇(VIP典藏版)

摘要: 本文整理了IDEA开发工具的实用配置与常见问题解决方案,涵盖四大主题:1)基础配置(插件、背景、快捷键、内存优化等);2)开发使用(Maven配置、代码提示、XML背景色调整等);3)Git操作(项目分享、账号切换、代理设置);4)常见问题(启动按钮灰色、索引卡顿等)。重点包括:代码提示不区分大小写设置、XML黄色背景消除、多文件Tab显示优化、Git账号修改方法等。通过清晰的步骤和配图,帮助开发者快速解决实际问题,提升IDEA使用效率。

慕白Lee的博客 18万+
上一篇: Q:java中关于String类型的一个问题
下一篇: Q:JDK6中的substring()方法容易导致内存泄露而JDK7不会出现这样的情况的原因
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值