java序列化详解


前言

对象序列化,就是为了保存在内存中的各种对象的状态,并且可以把保存的对象状态再读出来(反序列化)。虽然有各种各样的方法来保存对象状态,但是Java给你提供一种公共的保存对象状态的方法,那就是序列化。


提示:以下是本篇文章正文内容,下面案例可供参考

一、序列化和反序列化是什么?

序列化:把Java对象转换为字节序列的过程。(理解为:加密过程)

反序列化:把字节序列恢复为Java对象的过程。(理解为:解密过程)

二、为什么需要序列化和反序列化?

需要序列化和反序列化,主要是因为Java对象是在JVM中生成的,是内存中的数据,如果需要把对象的字节序列远程传输或保存到硬盘上时,就需要将Java对象转换成二进制流,这个转换过程就是序列化。
  Java平台允许我们在内存中创建可复用的Java对象,但只有当JVM(Java虚拟机)处于运行时,这些对象才可能存在,也就是这些对象的生命周期不会比JVM的生命周期更长。但在现实应用中,就可能要求在JVM停止运行之后能够保存指定的对象(持久化对象),并在将来重新读取被保存的对象。  
  而且网络通信时,无论是何种类型的数据,都以字节序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。这也是序列化和反序列化的必要性

**也就是说,以下情况需要序列化**
    当你想把的内存中的对象保存到一个文件中或者数据库中时候;
  当你想用序列化在网络上传送对象的时候;
  当你想通过RMI传输对象的时候;

三、序列化注意事项

1.实现

 实现了如下两个接口之一的类的对象才能被序列化:

1) Serializable

2) Externalizable

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

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

同时:使用writeObject() 和readObject()方法的对象必须已经被序列化

2.关于serialVersionUID

如果serialVersionUID定义,系统就会自动生成一个。此时,如果在序列化后我们将该类代码作了改动(包括类名、接口名、方法、属性),系统在反序列化时会重新生成一个新的serialVersionUID然后去和已经序列化的对象进行比较,就会报序列号版本不一致的错误。为了避免这种问题,
一般系统都会要求实现Serialiable接口的类显式的声明(定义)一个serialVersionUID。
- 给对象所属的类加一个serialVersionUID
- private static final long serialVersionUID = 42L;

所以显式定义serialVersionUID有如下两种作用:
  1、 希望类的不同版本对序列化兼容时,需要确保类的不同版本具有相同的serialVersionUID;
  2、 不希望类的不同版本对序列化兼容时,需要确保类的不同版本具有不同的serialVersionUID。

总结

1、当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;
2、当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;
3、不是所有的对象都可以序列化。
  比如:
    安全方面的原因,比如一个对象拥有private,public等field,对于一个要传输的对象,
      比如写到文件,或者进行rmi传输 等等,在序列化进行传输的过程中,这个对象的private等域是不受保护的,也就是说,是不安全的。

原因有很多,不能因为方便,全部使用序列化,忽略其他问题,比如安全性。


总结

以上为学习笔记,为网上总结整理得来!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值