加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

面试官:您能说说序列化和反序列化吗?是怎么实现的?什么场景下需要它?

发布时间:2019-08-28 06:23:04 所属栏目:建站 来源:xcbey0nd
导读:序列化和反序列化是Java中最基础的知识点,也是很容易被大家遗忘的,虽然天天使用它,但并不一定都能清楚的说明白。我相信很多小伙伴们掌握的也就几句概念、关键字(Serializable)而已,如果深究问一下序列化和反序列化是如何实现、使用场景等,就可能不知
副标题[/!--empirenews.page--]

序列化和反序列化是Java中最基础的知识点,也是很容易被大家遗忘的,虽然天天使用它,但并不一定都能清楚的说明白。我相信很多小伙伴们掌握的也就几句概念、关键字(Serializable)而已,如果深究问一下序列化和反序列化是如何实现、使用场景等,就可能不知所措了。

面试官:您能说说序列化和反序列化吗?是怎么实现的?什么场景下需要它?

在每次我作为面试官,考察Java基础时,通常都会问到序列化、反序列化的知识点,用以衡量其Java基础如何。当被问及Java序列化是什么?反序列化是什么?什么场景下会用到?如果不用它,会出现什么问题等,一般大家回答也就是几句简单的概念而已,有的工作好几年的应聘者甚至连概念都说不清楚,一脸闷逼。

本文就序列化和反序列化展开深入的探讨,当被别人问及时,不至于一脸闷逼、尴尬,或许会为你以后的求职面试中增加一点点筹码。

一、基本概念

1、什么是序列化和反序列化

序列化是指将Java对象转换为字节序列的过程,而反序列化则是将字节序列转换为Java对象的过程。 Java对象序列化是将实现了Serializable接口的对象转换成一个字节序列,能够通过网络传输、文件存储等方式传输 ,传输过程中却不必担心数据在不同机器、不同环境下发生改变,也不必关心字节的顺序或其他任何细节,并能够在以后将这个字节序列完全恢复为原来的对象(恢复这一过程称之为反序列化)。

对象的序列化是非常有趣的,因为利用它可以实现轻量级持久性,“持久性”意味着一个对象的生存周期不单单取决于程序是否正在运行,它可以生存于程序的调用之间。通过将一个序列化对象写入磁盘,然后在重新调用程序时恢复该对象,从而达到实现对象的持久性的效果。

本质上讲,序列化就是把实体对象状态按照一定的格式写入到有序字节流,反序列化就是从有序字节流重建对象,恢复对象状态。

2、为什么需要使用序列化和反序列化

我们知道,不同进程/程序间进行远程通信时,可以相互发送各种类型的数据,包括文本、图片、音频、视频等,而这些数据都会以二进制序列的形式在网络上传送。

那么当两个Java进程进行通信时,能否实现进程间的对象传送呢?当然是可以的!如何做到呢?这就需要使用Java序列化与反序列化了。发送方需要把这个Java对象转换为字节序列,然后在网络上传输,接收方则需要将字节序列中恢复出Java对象。

我们清楚了为什么需要使用Java序列化和反序列化后,我们很自然地会想到Java序列化有哪些好处:

  • 实现了数据的持久化,通过序列化可以把数据永久地保存到硬盘上(如:存储在文件里),实现永久保存对象。
  • 利用序列化实现远程通信,即:能够在网络上传输对象。

二、如何实现Java序列化和反序列化

只要对象实现了Serializable、Externalizable接口(该接口仅仅是一个标记接口,并不包含任何方法),则该对象就实现了序列化。

1、具体是如何实现的呢?

序列化,首先要创建某些OutputStream对象,然后将其封装在一个ObjectOutputStream对象内,这时调用writeObject()方法,即可将对象序列化,并将其发送给OutputStream(对象序列化是基于字节的,因此使用的InputStream和OutputStream继承的类)。

面试官:您能说说序列化和反序列化吗?是怎么实现的?什么场景下需要它?

反序列化,即反向进行序列化的过程,需要将一个InputStream封装在ObjectInputStream对象内,然后调用readObject()方法,获得一个对象引用(它是指向一个向上转型的Object),然后进行类型强制转换来得到该对象。

面试官:您能说说序列化和反序列化吗?是怎么实现的?什么场景下需要它?

假定一个User类,它的对象需要序列化,可以有如下三种方法:

(1)若User类仅仅实现了Serializable接口,则可以按照以下方式进行序列化和反序列化。

  • ObjectOutputStream采用默认的序列化方式,对User对象的非transient的实例变量进行序列化。
  • ObjcetInputStream采用默认的反序列化方式,对对User对象的非transient的实例变量进行反序列化。

(2)若User类仅仅实现了Serializable接口,并且还定义了readObject(ObjectInputStream in)和writeObject(ObjectOutputSteam out),则采用以下方式进行序列化与反序列化。

  • ObjectOutputStream调用User对象的writeObject(ObjectOutputStream out)的方法进行序列化。
  • ObjectInputStream会调用User对象的readObject(ObjectInputStream in)的方法进行反序列化。

(3)若User类实现了Externalnalizable接口,且User类必须实现readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法,则按照以下方式进行序列化与反序列化。

  • ObjectOutputStream调用User对象的writeExternal(ObjectOutput out))的方法进行序列化。
  • ObjectInputStream会调用User对象的readExternal(ObjectInput in)的方法进行反序列化。

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

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

2、序列化和反序列化示例

为了更好的理解序列化和反序列化的过程,举例如下:

  1. public class SerialDemo { 
  2.   
  3.     public static void main(String[] args) throws IOException, ClassNotFoundException { 
  4.         // 序列化对象User 
  5.         FileOutputStream fos = new FileOutputStream("object.txt"); 
  6.         ObjectOutputStream oos = new ObjectOutputStream(fos); 
  7.         User user1 = new User("xcbeyond", "123456789"); 
  8.         oos.writeObject(user1); 
  9.         oos.flush(); 
  10.         oos.close(); 
  11.   
  12.         // 反序列化 
  13.         FileInputStream fis = new FileInputStream("object.txt"); 
  14.         ObjectInputStream ois = new ObjectInputStream(fis); 
  15.         User user2 = (User) ois.readObject(); 
  16.         System.out.println(user2.getUsername()+ "," + user2.getPassword()); 
  17.     } 
  1. // 对象User,对其实现了Serializable接口 
  2. public class User implements Serializable { 
  3.     private String username; 
  4.     private String password; 
  5.      
  6.     …… 
  7.   

3、什么场景下需要序列化

  • 当你想把的内存中的对象状态保存到一个文件中或者数据库中时候。
  • 当你想用套接字在网络上传送对象的时候。
  • 当你想通过RMI传输对象的时候。

三、注意事项

1、当一个父类实现序列化,子类就会自动实现序列化,不需要显式实现Serializable接口。

2、当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化。

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读