专栏首页葫芦java 序列化Serializable

java 序列化Serializable

程序员面试时,序列化知识点经常会遇到。

张工是一名java程序员,工作5年了,一直从事java开发。最近到某互联网公司面试,做了笔试题后,有一道笔试题是这样子的:Serializable有什么作用,张工没有作答,面谈时面试官又问了,张工回答不出个所以然。面试官:你都工作五年了,连序列化都不知道,你这5年都干些什么了?张工一脸的无助,不过确实不应该,类似Serializable序列化这样的知识点,平时应该不会少用。

小编之前参加的笔试也遇到了关于序列化的问题,关于序列化我们都能知道个大概,但要是能进一步分析个所以然那就更好了,这样能给面试官留下更好的印象。

一般情况下,我们在定义实体类时会继承Serializable接口,类似这样:

我们在实体类中引用了Serializable这个接口,那么这个接口到底有什么?细心的你会发现我们还定义了个serialVersionUID变量。这个变量到底有什么作用?

  • 什么是Serializable接口?

一个对象序列化的接口,一个类只有实现了Serializable接口,它的对象才能被序列化。

  • 什么是序列化?

序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。

  • 为什么要序列化对象?

把对象转换为字节序列的过程称为对象的序列化把字节序列恢复为对象的过程称为对象的反序列化什么情况下需要序列化?

当我们需要把对象的状态信息通过网络进行传输,或者需要将对象的状态信息持久化,以便将来使用时都需要把对象进行序列化

那为什么还要继承Serializable。那是存储对象在存储介质中,以便在下次使用的时候,可以很快捷的重建一个副本。

或许你会问,我在开发过程中,实体并没有实现序列化,但我同样可以将数据保存到mysql、Oracle数据库中,为什么非要序列化才能存储呢?

我们来看看Serializable到底是什么,跟进去看一下,我们发现Serializable接口里面竟然什么都没有,只是个空接口

一个接口里面什么内容都没有,我们可以将它理解成一个标识接口。

比如在课堂上有位学生遇到一个问题,于是举手向老师请教,这时老师帮他解答,那么这位学生的举手其实就是一个标识,自己解决不了问题请教老师帮忙解决。在Java中的这个Serializable接口其实是给jvm看的,通知jvm,我不对这个类做序列化了,你(jvm)帮我序列化就好了。

Serializable接口就是Java提供用来进行高效率的异地共享实例对象的机制,实现这个接口即可。

  • 什么是JVM?

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

  • 为什么要定义serialversionUID变量?

简单看一下 Serializable接口的说明

从说明中我们可以看到,如果我们没有自己声明一个serialVersionUID变量,接口会默认生成一个serialVersionUID

但是强烈建议用户自定义一个serialVersionUID,因为默认的serialVersinUID对于class的细节非常敏感,反序列化时可能会导致InvalidClassException这个异常。

在前面我们已经新建了一个实体类User实现Serializable接口,并且定义了serialVersionUID变量。

我们把User写到文件,然后读取出来。

是的,你没有看错,序列化与反序列化操作过程就是这么的简单。只需要将User写入到文件中,然后再从文件中进行恢复,恢复后得到的内容与之前完全一样,但是两者是不同的对象。前面提到过一个问题,如果将serialVersionUID变量去掉,我们来看看,会发生什么事情。

刚开始提到了,serialVersionUID要不要指定呢?如果不指定会出现什么样的后果?如果指定了以后后边的值又代表着什么意思呢?既然系统指定了这个字段,那么肯定是有它的作用的。

这个serialVersionUID是用来辅助对象的序列化与反序列化的,原则上序列化后的数据当中的serialVersionUID与当前类当中的serialVersionUID一致,那么该对象才能被反序列化成功。这个serialVersionUID的详细的工作机制是:在序列化的时候系统将serialVersionUID写入到序列化的文件中去,当反序列化的时候系统会先去检测文件中的serialVersionUID是否跟当前的文件的serialVersionUID是否一致,如果一直则反序列化成功,否则就说明当前类跟序列化后的类发生了变化,比如是成员变量的数量或者是类型发生了变化,那么在反序列化时就会发生crash,并且回报出错误:

java.io.InvalidClassException: User; local class incompatible: stream classdesc serialVersionUID = -1451587475819212328, local class serialVersionUID = -3946714849072033140at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:699)at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1885)at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1751)at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2042)at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)at Main.readUser(Main.java:32)at Main.main(Main.java:10)

本文转自:洪生鹏

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 07.Django学习之model进阶

    使用Python 的切片语法来限制查询集记录的数目 。它等同于SQL 的LIMIT 和OFFSET 子句。

    changxin7
  • Weblogic反序列化历史漏洞全汇总

    序列化是让Java对象脱离Java运行环境的一种手段,可以有效的实现多平台之间的通信、对象持久化存储。

    Jayway
  • 基于nGrinder下的web网站性能测试

    nGrinder 看名字估计很多人就猜到跟Grinder有关系。nGrinder是韩国一家公司居于Grinder二次开发的一个性能平台。nGrinder具有 开...

    用户6367961
  • 基于设备指纹零感验证系统

    作者: 我是小三 博客: http://www.cnblogs.com/2014asm/ 由于时间和水平有限,本文会存在诸多不足,希望得到您的及时反馈与指正,多...

    我是小三
  • 一起学Rust-实战leetcode(三)

    之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。

    MikeLoveRust
  • 利用nohup后台运行jar文件包程序

    java -jar XXX.jar 特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出

    Java架构师历程
  • Springboot集成swagger2生成接口文档

    原文出处:https://www.cnblogs.com/jstarseven/p/11509884.html 作者:jstarseven 码字挺辛苦的....

    大道七哥
  • Spring MVC适配器模式实践之HandlerAdapter源码分析【享学Spring MVC】

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    BAT的乌托邦
  • itext根据模板生成pdf(支持分页)

    // 利用模板生成pdf public static void pdfout(Map<String,Object> o,String newPDFPa...

    用户4478423
  • 使用JMeter做MongoDB性能测试

    对大多数应用环境来说,数据库是一个关键要素。如何存储数据以及在哪里存储数据,对整个系统的性能会产生巨大影响。因此,在做开发之前,数据库的选择肯定是最重要的决定之...

    MongoDB中文社区

扫码关注云+社区

领取腾讯云代金券