美文网首页
Java序列化

Java序列化

作者: 云芈山人 | 来源:发表于2021-07-04 23:54 被阅读0次

为什么设计了Java序列化的功能?

Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM运行时,这些对象才存在,即这些对象的生命周期不会大于JVM的生命周期。但现实应用中,就可能要求JVM在停止运行后依然能保存(持久化)指定的对象【保存(持久化)对象及其状态到内存或磁盘中】,并在将来重新读取被保存的对象。Java对象序列化能够帮助我们实现该功能。

除了在持久化对象时会用到对象序列化之外,当使用RMI(远程方法调用),或在网络中传递对象时,都会用到对象序列化。Java序列化API为处理对象序列化提供了一个标准机制,该API简单易用。

Java提供了一种对象序列化的机制。该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中的数据类型。
将序列化对象写入文件之后,可以从文件中读取出来,并且对它进行反序列化,也可以说,对象的类型信息、对象的数据、对象的数据类型可以在内存中新建对象。

注意:使用Java对象序列化,在保存对象时,会把其状态保存为一组字节,在未来,再将这些字节组装成对象。对象序列化保存的是对象的“状态”,即它的成员变量。由此可知,Java序列化不保存静态变量!

类ObjectInputStream() 和ObjectOutputStream()是最高层次的数据流,它们包含反序列化和序列化的功能。

如何实现序列化和反序列化

实现序列化方法

1. 实现Serializable接口
  • 该接口只是一个可序列化的标志,并没有包含实际的属性和方法。序列化传输时使用writeObject和readObject方法,并通过反射调用ObjectInputStream和ObjectOutputStream,如果没有设置Serializable则报错。
/*
 * @author  unascribed
 * @see java.io.ObjectOutputStream
 * @see java.io.ObjectInputStream
 * @see java.io.ObjectOutput
 * @see java.io.ObjectInput
 * @see java.io.Externalizable
 * @since   JDK1.1
 */
public interface Serializable {
}
  • 如果不在该方法中添加readObject()和writeObject()方法,则采取默认的序列化机制。如果添加了这两个方法之后还想利用Java默认的序列化机制,则在这两个方法中分别调用defaultReadObject()和defaultWriteObject()两个方法。

  • 序列化只保存对象的状态,不保存对象的方法。

  • 父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口。

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

  • 并非所有的对象都可以序列化。

    1. 安全方面的考虑:如一个对象拥有private、public等field,对于一个要传输的对象,比如写到文件,或者进行RMI传输等等,在序列化进行传输的过程中,private等域不受保护。
    2. 资源分配的考虑:比如socket、thread类,如果可以序列化,进行传输或保存,也无法对他们进行重新的资源分配,且没必要。
  • 序列化前和序列化后,对象的关系是equals,深复制。

  • Transient 关键字阻止该变量被序列化到文件中。

    1. 在变量声明前加上 Transient 关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null。
    2. 服务器端给客户端发送序列化对象数据,对象中有一些数据是敏感的,比如密码字符串等,希望对该密码字段在序列化时,进行加密,而客户端如果拥有解密的密钥,只有在客户端进行反序列化时,才可以对密码进行读取,这样可以一定程度保证序列化对象的数据安全。
    3. 声明为static和transient类型的成员数据不能被序列化。因为static代表类的状态(序列化的是对象的状态不是类的状态), transient代表对象的临时数据。
  • 对象的类名、属性都会被序列化,方法不会被序列化。

优点:内建支持,易于实现。
缺点:占用空间过大,由于额外的开销导致速度变比较慢 。

2. 实现Externalizable 方法(外部化)

自己对要序列化的内容进行控制,控制哪些属性能被序列化,哪些不能被序列化。

public interface Externalizable extends java.io.Serializable {
     void writeExternal(ObjectOutput out) throws IOException;
     void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
}

优点:开销较少(程序员决定存储什么),可能的速度提升。
缺点:虚拟机不提供任何帮助,也就是说所有的工作都落到了开发人员的肩上。

3. Serializable 与 Externalizable的区别
  • 通过Serializable接口对对象序列化的支持是内建于核心 API 的;java.io.Externalizable的所有实现者必须提供读取和写出的实现。
  • 序列化会自动存储必要的信息,用以反序列化被存储的实例;外部化则只保存被存储的类的标识。

反序列化

虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化 ID 是否一致(就是 private static final long serialVersionUID)。

  1. 实现Serializable接口的对象在反序列化时不需要调用对象所在类的构造方法,完全基于字节。
  2. 实现Externalizable接口的方法在反序列化时会调用构造方法。

常见的序列化协议

COM

主要用于Windows平台,并没有真正跨平台,另外COM的序列化原理利用了编译器中虚表,使得其学习成本巨大。

CORBA

是早期比较好的实现跨平台、跨语言的序列化协议。但它的主要问题是参与方过多带来的版本过多,兼容性较差,使用复杂晦涩。

XML&SOAP

  • XML是一种常用的序列化和反序列化协议,具有跨机器、跨语言等优点。
  • SOAP(Simple Object Access protocol)是一种被广泛应用的,基于XML为序列化和反序列化协议的结构化消息传递协议。SOAP具有安全、可扩展、跨语言、跨平台并支持多种传输层协议。

JSON(JavaScript Object Notation)

  • 这种Associative array 格式非常符合工程师对对对象的理解。
  • 它保持了XML的人眼可读(Human-readable)的优点。
  • 相对于XML而言,序列化后的数据更加简洁。
  • 它具备JavaScript的先天性支持,所以被广泛应用于Web browser的应用场景中,是Ajax的事实标准协议。
  • 与XML相比,器协议比较简单,解析速度比较快。
  • 松散的Associative array使得其具有良好的可扩展性和兼容性。

Thrift

Facebook开源提供的一个高性能,轻量级RPC服务框架,其产生正是为了满足当前大数据量、分布式、跨语言、跨平台数据通讯的需求。Thrift在空间开销和解析性能上有了比较大的提升,对于性能要求比价高的分布式系统,它是一个优秀的RPC解决方案;但是由于Thrift的序列化被嵌入到Thrift框架里面,Thrift框架本身并没有透出序列化和反序列化的接口,这导致其很难和其他传输层协议共同使用。

相关文章

  • Java-序列化-反序列化

    Thanks Java基础学习总结——Java对象的序列化和反序列化java序列化反序列化原理Java 序列化的高...

  • java序列化那些事儿

    java序列化作用 在说java序列化的作用之前,先说下什么是java序列化吧。java序列化是指把java对象转...

  • Java序列化

    Java序列化的几种方式以及序列化的作用 Java基础学习总结——Java对象的序列化和反序列化

  • Java序列化机制

    Java序列化机制 序列化和反序列化 Java序列化是Java内建的数据(对象)持久化机制,通过序列化可以将运行时...

  • Java 序列化 之 单例模式

    序列化相关文章: Java 序列化 之 Serializable Java 序列化之 Externalizable...

  • java 序列化 原理解析

    序列化相关文章: Java 序列化 之 Serializable Java 序列化之 Externalizable...

  • 认识Java序列化

    我的个人博客,认识Java序列化 引言 将 Java 对象序列化为二进制文件的 Java 序列化技术是 Java ...

  • JDK 序列化

    序列化和分序列化概念 什么是序列化和反序列化 Java序列化是指把Java对象转换为字节序列的过程,而Java反序...

  • Spark序列化

    Java序列化 有关Java对象的序列化和反序列化也算是Java基础的一部分,首先对Java序列化的机制和原理进行...

  • Serializable中为什么要设置UID

    1、什么是Java序列化与反序列化 Java序列化是指把Java对象保存为二进制字节码的过程,Java反序列化是指...

网友评论

      本文标题:Java序列化

      本文链接:https://www.haomeiwen.com/subject/dxqpultx.html