本博客主要转自如下链接

http://blog.csdn.net/javazejian/article/details/52665164

这篇文章写的不错,但是有些地方我估计博主没有亲自测试,所以有些地方我亲测后发现其实他说的不对,大家可以先看看他写的,然后再看看我下面说的具体哪里不对了

先说说serialVersionUID的用途:

其实一个类要实现序列化和反序列化,不声明serialVersionUID是可行的,serialVersionUID主要是辅助序列化和反序列化,序列化和反序列化的时候,serialVersionUID必须一致,反序列化才会成功。具体的序列化过程是这样的:序列化操作的时候系统会把当前类的serialVersionUID写入到序列化文件中,当反序列化时系统会去检测文件中的serialVersionUID,判断它是否与当前类的serialVersionUID一致,如果一致就说明序列化类的版本与当前类版本是一样的,可以反序列化成功,否则失败。报出如下UID错误:

Exception in thread "main" java.io.InvalidClassException: com.zejian.test.Client;
local class incompatible: stream classdesc serialVersionUID = -2083503801443301445,
local class serialVersionUID = -4083503801443301445

原博文中主要错在这句话  “因此强烈建议指定serialVersionUID,这样的话即使微小的变化也不会导致crash的出现,如果不指定的话只要这个文件多一个空格,系统自动生成的UID就会截然不同的,反序列化也就会失败

亲测发现,当不指定serialVersionUID的时候,将对象序列化到文件中后,如果仅仅在对象文件中添加了一些空格或者换行,反序列化仍然会成功,而并不是那篇博客中说的加个空格就会反序列化失败。原因应该是serialVersionUID的生成方法是基于对象的一些属性生成的,而跟这个对象文件中的空格换行等是没有关系的。

我试着在没有指定的serialVersionUID的情况下,序列化后,在对象中添加了一个属性,并对之前生成的序列化后的文件进行反序列化,发现失败了,抛了上述说的异常,这是因为在对象中添加了属性后,由于没有指定serialVersionUID,所以系统会自动根据这个对象的属性等产生一个新的serialVersionUID,这就导致这个serialVersionUID与序列化文件中的serialVersionUID不一致,从而反序列化失败。

接着,我为对象加了serialVersionUID属性,在intellij idea中为一个对象加serialVersionUID的方法如下:

Setting->Inspections->Serialization issues->Serializable class without ’serialVersionUID’
选中以上后,在你的class中:光标定位在类名前,按 Alt+Enter 就会提示自动创建 serialVersionUID 了。

在添加了 serialVersionUID的对象中,我重新进行了序列化,序列化后,我在对象中添加了一个新的属性,也修改了原有的属性,但是serialVersionUID没有变,所以序列化文件中的serialVersionUID和对象文件中的serialVersionUID一致,反序列化都成功,但是只会反序列化成功匹配上的属性值,没有匹配上的都会为null。如果在序列化后修改了serialVersionUID的值,则反序列化会失败,抛出上述异常。

下面是上述博客中测试的例子,我进行了点修改方便测试:

被序列化对象Client:注意,这个对象中的几个object相关方法是用来自定义序列化和反序列化过程的,我们自定义哪些属性需要序列化,上述测试我把object相关方法都注释掉了。

package com.sogou.study.serialize;/*** Created by denglinjie on 2016/9/29.*/
import java.io.IOException;
import java.io.ObjectStreamException;
import java.io.Serializable;public class Client implements Serializable{/*** 生成序列号标识*/private static final long serialVersionUID = -2083503801443301445L;private int id;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}/*** 序列化时,* 首先系统会先调用writeReplace方法,在这个阶段,* 可以进行自己操作,将需要进行序列化的对象换成我们指定的对象.* 一般很少重写该方法* @return* @throws ObjectStreamException*/private Object writeReplace() throws ObjectStreamException {System.out.println("writeReplace invoked");return this;}/***接着系统将调用writeObject方法,* 来将对象中的属性一个个进行序列化,* 我们可以在这个方法中控制住哪些属性需要序列化.* 这里只序列化name属性* @param out* @throws IOException*/private void writeObject(java.io.ObjectOutputStream out) throws IOException {System.out.println("writeObject invoked");//这里自定义只序列化了对象的name属性到文件中out.writeObject(this.name == null ? "zejian" : this.name);}/*** 反序列化时,系统会调用readObject方法,将我们刚刚在writeObject方法序列化好的属性,* 反序列化回来.然后通过readResolve方法,我们也可以指定系统返回给我们特定的对象* 可以不是writeReplace序列化时的对象,可以指定其他对象.* @param in* @throws IOException* @throws ClassNotFoundException*/private void readObject(java.io.ObjectInputStream in) throws IOException,ClassNotFoundException {System.out.println("readObject invoked");//由于序列化的时候自定义只序列化了name属性,所以这里读出来的object就是name的值,可以直接转换成Stringthis.name = (String) in.readObject();System.out.println("got name:" + name);}/*** 通过readResolve方法,我们也可以指定系统返回给我们特定的对象* 可以不是writeReplace序列化时的对象,可以指定其他对象.* 一般很少重写该方法* @return* @throws ObjectStreamException*/private Object readResolve() throws ObjectStreamException {System.out.println("readResolve invoked");return this;}
}

序列化类

package com.sogou.study.serialize;/*** Created by denglinjie on 2016/9/29.*/import java.io.FileOutputStream;
import java.io.ObjectOutputStream;public class SerializeTest {public static void main(String[] args) throws Exception {//把对象序列化到文件Client client = new Client();client.setId(11);client.setName("client");ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream("D:\\test\\file1.txt"));oo.writeObject(client);oo.close();}
}

反序列化类:

package com.sogou.study.serialize;/*** Created by denglinjie on 2016/9/29.*/import java.io.FileInputStream;
import java.io.ObjectInputStream;public class UnSerializeTest {public static void main(String[] args) throws Exception {//反序列化到内存ObjectInputStream oi = new ObjectInputStream(new FileInputStream("D:\\test\\file1.txt"));Client c_back = (Client) oi.readObject();System.out.println(c_back.getName());System.out.println(c_back.getId());oi.close();}
}

Java对象的serialVersionUID在序列化和反序列化的用途相关推荐

  1. java clone 序列化_关于Java对象深度Clone以及序列化与反序列化的使用

    ‍        我们可以利用clone方法来实现对象只见的复制,但对于比较复杂的对象(比如对象中包含其他对象,其他对象又包含别的对象.....)这样我们必须进行层层深度clone,每个对象需要实现 ...

  2. java对象流保存表格,序列化表格 (Java 2 Platform SE 5.0)

    此字段有两种可能的解释: startMode == DOW_IN_MONTH startDay 指示夏令时是在 startMonth 月份中的哪个日期开始的,该日期可以是从 1 到 28.30 或 3 ...

  3. Java与iOS对话:Java对象与Apple plist序列化

    我很高兴地宣布我的第一个开源项目java-plist-serializer可以帮助您将Java(尤其是基于Spring的应用程序)与iOS应用程序集成.   背景 我正在将Java Webapp作为后 ...

  4. JAVA进阶教学之(序列化和反序列化)

    目录 1.序列化Serialize和反序列化的概念 2.序列化和反序列化的代码演示: 3.序列化多个对象(序列化集合) 4.transient关键字将部分属性不参与序列化 1.序列化Serialize ...

  5. 当Java泛型擦除遇到JSON序列化和反序列化

    当Java泛型类型擦除遇到JSON序列化和反序列化 目录 当Java泛型类型擦除遇到JSON序列化和反序列化 前言 测试 前言 -最近看到了Spring 关于 RestTemplate的源码实现又有了 ...

  6. java序列化和反序列化对象_java中的序列化与反序列化,还包括将多个对象序列化到一个文件中...

    package Serialize; /** * Created by hu on 2015/11/7. */ //实现序列化必须实现的接口,这就是一个空接口,起到标识的作用 import java. ...

  7. 序列化: 一个老家伙的咸鱼翻身(Java对象、XML、JSON、反序列化)

    转自:码农翻身(微信号:coderising) 1.寒冬的蛰伏 这里的工作很繁忙,一年365天, 一天24小时几乎不停工. 但是我却是一个闲人, 因为我做的工作最近用的人太少了, 经常被冷落在一边. ...

  8. 传递实体类对象_Java I/O 流之对象流中的序列化和反序列化

    一.概念 当两个进程远程通信时,彼此可以发送各种类型的数据. 无论是何种类型的数据,都会以二进制序列的形式在网络上传送.比如,我们可以通过 http 协议发送字符串信息:我们也可以在网络上直接发送 J ...

  9. ios plist 国际化_Java与iOS对话:Java对象与Apple plist序列化

    ios plist 国际化 我很高兴地宣布我的第一个开源项目java-plist-serializer可以帮助您将Java(尤其是基于Spring的应用程序)与iOS应用程序集成在一起.   背景 我 ...

最新文章

  1. 两阶段提交(Two-Phase Commit)
  2. 1.spring:helloword/注入/CDATA使用/其他Bean/null级联/p命名空间
  3. DOM_05之DOM、BOM常用对象
  4. 【网络知识】1. 路由器或网桥的2.4G和5G的Wi-Fi各自优缺点对比
  5. Spring boot指定日志配置
  6. 【每周CV论文推荐】 初学高效率CNN模型设计应该读的文章
  7. 字符串的转换相关方法
  8. (1.1)HarmonyOS鸿蒙中Ability概念及意义
  9. [Ext JS 4] 实战之Grid, Tree Gird 动态添加列
  10. 别轻易接受父母的建议
  11. 用JAVA输入一位整数,当输入1-7时显示对应的英文星期名称缩写
  12. html 插件 firefox,firefox插件 怎么在firefox里添加插件
  13. codeforces CF487E Tourists 边双连通分量 树链剖分
  14. 如何才能做好短线交易?这三点你要知道!
  15. 快速应对面试--分门别类--7.栈和队列
  16. 控件之Scale LabelScale
  17. 【python小作业】编写函数,接收一个任意字符串,返回其中最长的数字字串。要求使用正则表达式。
  18. 什么是redis??
  19. 罗丹明RB/四甲基罗丹明标记软骨素chondroitin, Rhodamine B/TRITC labeled;Rhodamine B/TRITC-chondroitin
  20. 30.1lvs-adm与ipvsadm命令

热门文章

  1. MyEclipse项目无法自动编译解决方案
  2. Atcoder Yahoo Programming Contest 2019 简要题解
  3. jquery项目中一些常用方法
  4. JS引擎查找属性的原理
  5. java使用内部类的好处及其初始化
  6. 全面进军javascript!
  7. 使用OLE DB方式连接常用数据库的连接字符串的设置
  8. 【测试】软件测试计划的编写
  9. gradle普通项目构建外部依赖jar的终极方法gradle瘦身
  10. 看完尤雨溪338条知乎回答后,我突然找到了前进的方向