`

对象序列化知识小结

阅读更多

 

对象序列化

 

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

序列化的目的:以某种存储形式使自定义对象持久化,将对象从一个地方传递到另一个地方。

对象的序列化主要有三种用途:

1)    把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;

2)    在网络上传送对象的字节序列。

3)    通过序列化在进程间传递对象。

 

序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化的对象进行读写操作,也可以将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时引发的问题。

序列化是将对象转换为容易传输的格式的过程,例如,可以序列化一个对象,然后使用HTTP通过Internet在客户端和服务器之间传输该对象,在另一端,反序列化将从该流重新构造对象。序列化是对象永久化的一种机制。

 

一般程序在运行时产生对象,这些对象随着程序停止运行而消失,但如果我们想把某些对象(因为是对象所以有各自不同的特性)保存下来,在程序终止运行后,这些对象仍然存在,可以在程序再次运行时,读取这些对象值或者在其他程序中利用这些保存下来的对象,这种情况下就要用到对象的序列化。

 

序列化的实现:需要被序列化的类要实现Serializable接口,该接口没有需要实现的方法,实现该接口只是为了标注该对象是可以被序列化的。只有序列化的对象才可以存储在存储设备上,为了对象的序列化需要继承的接口也只是象征性的接口而已,也就是继承这个接口说明这个对象可以被序列化了,没有其他的目的。

 

JDK类库中的序列化API

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

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

对象序列化包括如下步骤:

1 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;

2 通过对象输出流的writeObject()方法写对象。

对象反序列化的步骤如下:

1 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;

2 通过对象输入流的readObject()方法读取对象。

 

ObjectOutputStream只能对Serializable接口的类的对象进行序列化。默认情况下,ObjectOutputStream按照默认方式序列化,这种序列化方式仅仅对对象的非transient的实例变量进行序列化,而不会序列化对象的transient的实例变量,也不会序列化静态变量。当ObjectOutputStream按照默认方式反序列化时,具有如下特点:

  1 如果在内存中对象所属的类还没有被加载,那么会先加载并初始化这个类。如果在classpath中不存在相应的类文件,那么会抛出ClassNotFoundException

  2 在反序列化时不会调用类的任何构造方法。

  如果用户希望控制类的序列化方式,可以在可序列化类中提供以下形式的writeObject()readObject()方法。

 

private void writeObject(java.io.ObjectOutputStream out) throws IOException

private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException

 

当进行序列化的时候:

首先JVM会先调用writeReplace方法,在这个阶段,我们可以进行张冠李戴,将需要进行序列化的对象换成我们指定的对象.

跟着JVM将调用writeObject方法,来将对象中的属性一个个进行序列化,我们可以在这个方法中控制住哪些属性需要序列化.

当反序列化的时候:

JVM会调用readObject方法,将我们刚刚在writeObject方法序列化好的属性,反序列化回来.

然后在readResolve方法中,我们也可以指定JVM返回我们特定的对象(不是刚刚序列化回来的对象).

注意到在writeReplacereadResolve,我们可以严格控制singleton的对象,在同一个JVM中完完全全只有唯一的对象,控制不让singleton对象产生副本.

 

ObjectOutputStream对一个Customer对象进行序列化时,如果该对象具有writeObject()方法,那么就会执行这一方法,否则就按默认方式序列化。在该对象的writeObjectt()方法中,可以先调用ObjectOutputStreamdefaultWriteObject()方法,使得对象输出流先执行默认的序列化操作。同理可得出反序列化的情况,不过这次是defaultReadObject()方法。

 

 

有些对象中包含一些敏感信息,这些信息不宜对外公开。如果按照默认方式对它们序列化,那么它们的序列化数据在网络上传输时,可能会被不法份子窃取。对于这类信息,可以对它们进行加密后再序列化,在反序列化时则需要解密,再恢复为原来的信息。

 

Externalizable接口继承自Serializable接口,如果一个类实现了Externalizable接口,那么将完全由这个类控制自身的序列化行为。Externalizable接口声明了两个方法:

 

public void writeExternal(ObjectOutput out) throws IOException

public void readExternal(ObjectInput in) throws IOException , ClassNotFoundException

 

  前者负责序列化操作,后者负责反序列化操作。

  在对实现了Externalizable接口的类的对象进行反序列化时,会先调用类的不带参数的构造方法,这是有别于默认反序列方式的。如果把类的不带参数的构造方法删除,或者把该构造方法的访问权限设置为private、默认或protected级别,会抛出java.io.InvalidException: no valid constructor异常。

 

可序列化类的不同版本的序列化兼容性

 

凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:

 

private static final long serialVersionUID;

 

该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。如果接收者加载的该对象的类的 serialVersionUID 与对应的发送者的类的版本号不同,则反序列化将会导致 InvalidClassException

  serialVersionUID的取值是Java运行时环境根据类的内部细节自动生成的。如果对类的源代码作了修改,再重新编译,新生成的类文件的serialVersionUID的取值有可能也会发生变化。

  类的serialVersionUID的默认值完全依赖于Java编译器的实现,对于同一个类,用不同的Java编译器编译,有可能会导致不同的serialVersionUID,也有可能相同。为了提高serialVersionUID的独立性和确定性,强烈建议在一个可序列化类中显示的定义serialVersionUID,为它赋予明确的值。显式地定义serialVersionUID有两种用途:

  1 在某些场合,希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID

  2 在某些场合,不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有不同的serialVersionUID

分享到:
评论

相关推荐

    java 对象的序列化与反序列化

    下面是一些关于序列化的重要知识点: 1. **序列化标识符(SerialVersionUID)**:Java允许你为每个可序列化的类定义一个唯一的`serialVersionUID`,默认是由JVM根据类的结构计算出来的。如果类的版本更新导致结构变化...

    Java对象序列化

    ### Java对象序列化详解 #### 一、Java对象序列化概念 Java对象序列化是指将...理解序列化文件的格式以及序列化过程中的关键步骤,有助于开发者更好地掌握Java对象序列化的细节,并能够在实践中有效地应用这些知识。

    hessian学习基础篇——序列化和反序列化

    本文将深入探讨Hessian框架的基础知识,它是一个高效的二进制序列化协议,广泛应用于Java和.NET之间跨语言通信。通过学习Hessian,我们可以更有效地处理数据传输,提高应用性能。 首先,让我们理解什么是序列化。...

    Android 序列化对象存储到sharepreference

    本篇文章将详细探讨如何将Android序列化对象存储到SharedPreferences,以及这一过程中的关键知识点。 首先,我们来了解Android序列化。在Java中,一个类可以通过实现Serializable接口来使其实例可被序列化。当一个...

    C#序列化与反序列化

    本文将深入探讨C#中的序列化与反序列化机制,以及相关的知识点。 一、什么是C#序列化 C#序列化是指将一个对象的实例转换为一组字节流,这通常用于保存对象的状态以便稍后恢复,或者在网络之间传输对象。C#提供了...

    详细案例介绍json序列化与反序列化

    ### 详细案例介绍json序列化与反序列化 #### JSON简介 JSON(JavaScript Object Notation,JavaScript对象表示法)是一种...无论是初学者还是经验丰富的开发者,掌握JSON序列化与反序列化的知识都将大大提高工作效率。

    序列化与反序列化Demo

    序列化与反序列化是计算机科学中的重要概念,特别是在数据存储、网络通信和持久化对象等领域。简单来说,序列化是将对象的状态转换为可存储或传输的数据格式的过程,而反序列化则是将这种数据格式恢复为原来的对象...

    java序列化(Serializable)的作用和反序列化

    序列化是指将程序中的对象转换为字节流的过程,从而方便存储或传输这些对象。通常,序列化用于将对象的状态(即其实例变量的值,而非方法)持久化到磁盘上或在网络中进行传递。序列化机制是Java提供的强大工具之一,...

    Serializable在C#中的作用.NET 中的对象序列化

    ### C#中Serializable的作用与对象序列化详解 #### 一、引言 在现代软件开发中,特别是基于.NET框架的应用程序开发中,对象序列化是一项非常重要的技术。它允许将对象的状态转换为一种持久的形式(如文件或网络传输...

    序列化与反序列化示例

    在.NET框架中,序列化和反序列化是两个重要的概念,它们主要用来处理对象的状态转换。序列化是指将对象的状态转换为可以存储或传输的形式,如XML、JSON、二进制等;反序列化则是相反的过程,即从这种存储或传输的...

    序列化和反序列化复杂数据类型.docx

    - **序列化版本控制**:随着项目的发展,可能会对序列化对象进行更改,如添加新的字段等,这会导致序列化版本不一致的问题。为了解决这个问题,可以在类中添加一个`serialVersionUID`字段来固定版本,即使对象结构...

    序列化源码

    让我们进一步探讨序列化的一些关键知识点: 1. **序列化库选择**:有许多流行的序列化库可以选择,如Java中的Java Object Notation (JSON)库、Python的pickle模块、C#的BinaryFormatter或DataContractSerializer,...

    C# 类序列化 文件数据库 串行化

    总结来说,这个程序利用C#的类序列化技术,提供了一种有效的方法来存储和恢复大量数据,同时优化了文件拷贝和大规模数据管理。通过理解和应用这些知识点,开发者可以创建更灵活、高效的应用程序,特别是在处理数据...

    Java Json序列化与反序列化

    总结,Java中的JSON序列化与反序列化是数据交互的重要环节,Jackson和Gson是两个常用的库,它们提供了丰富的功能和良好的API设计,使得处理JSON数据变得简单高效。通过理解和掌握这些知识,开发者可以更好地在Java...

    图形的序列化MFC源代码

    总结一下,"图形的序列化MFC源代码"项目的关键知识点包括: 1. MFC库的使用,特别是`CObject`类和序列化机制。 2. 设计一个`CGraph`类,其中包含图形元素及其属性。 3. 实现`Serialize`函数来处理图形对象的序列化...

    c#,三层架构,抽象工厂,序列化于反序列化程序

    总结来说,“c#,三层架构,抽象工厂,序列化于反序列化程序”的项目中,开发人员采用了现代软件工程的最佳实践,包括分层设计以提高代码的可维护性和可扩展性,使用抽象工厂模式来实现灵活的对象创建,以及利用序列化...

    Java对象(最后面是序列化的知识)1

    Java编程语言中,对象的创建和管理涉及到一系列...总结来说,Java对象的生命周期涉及类加载、初始化,以及对象的创建、克隆、序列化和反序列化等步骤,每一步都可能需要特定的处理和优化,以满足不同的需求和安全考虑。

    MFC序列化存储代码

    3. **CArchive类**:`CArchive`是MFC提供的一个类,它提供了对二进制流的访问,可以将对象序列化到文件或内存中,也可以从文件或内存中反序列化对象。`CArchive`有两个主要的工作模式:存档模式(用于写入)和解档...

    S08-SnakeYaml反序列化1

    标题 "S08-SnakeYaml反序列化1" 提到的是关于使用SnakeYaml库进行Java对象的序列化和反序列化的知识点。SnakeYaml是一个开源的库,允许在Java应用程序中处理YAML格式的数据。以下是这些知识点的详细说明: **1. ...

    S01-java反序列化基础知识总结1

    在Java编程语言中,反序列化是将之前序列化的对象数据恢复为对象的过程。了解Java反序列化的基础知识有助于深入理解类加载机制,特别是在安全性、自定义类加载和内存管理方面。下面我们将详细讨论Java的类加载过程...

Global site tag (gtag.js) - Google Analytics