JAVA之序列化(Serialization)的理解

转载 2016年06月01日 15:01:48

1、什么是序列化

  Java是面向对象的编程语言,有时需要保存对象,并在下次使用时可以顺利还原该对象。由于这种需求很常见,所以Java API对此提供了支持,添加相关程序代码到标准类库中,并将保存和还原的过程称之为“对象序列化”。 
  Java SE7 文档中将与对象序列化的相关内容做了详细表述,将其称为: 
  “Java对象序列化规范”  Java Object Serialization Specification,网址为: 
  http://docs.oracle.com/javase/7/docs/platform/serialization/spec/serialTOC.html 


2、为什么叫序列化

  个人猜测: 
  由于保存对象的过程,是把对象保存为一连串字节流,而英文Serialization的意思“序列化”,所以序列化形象的表述了这个过程。 


3、序列化保存那些内容

  对象(object)是类(class)的一个实例(instance)。一个类中包含了变量(field)和函数(method)两个部分。同一个类的不同对象只是变量不同,所以Java API序列化过程中只保存了对象的变量部分。同样,由于静态变量(static field)是由同一个类的各个对象共用的,所以序列化过程中也不保存。 
  由于还原对象时需要在程序中动态创建该对象,所以程序也需要知道该对象的类定义,所以如果对象由一个程序序列化保存之后,由另外一个程序反序列化还原时,类文件也需要传送给该程序。这就需要扩展Java API序列化的功能,对其进行自定义。Java的远程方法调用(Remote Method Invocation, RMI)功能,就是以Java API序列化为基础,并进行了扩展。 




3、序列化的用途

 序列化主要有三个用途: 
  • 对象持久化(persistence)
  对象持久化是指延长对象的存在时间。通常状况下,当程序结束时,程序中的对象不再存在。 
  如果通过序列化功能,将对象保存到文件中,就可以延长对象的存在时间,在下次程序运行是再恢复该对象。 
  序列化将对象保存在文件中,是实现对象持久化的一种方式。持久化还有很多种方式,比如Hibernate框架就提供了一整套对象持久化的方案。 
  • 对象复制
  通过序列化,将对象保存在内存中,可以再通过此数据得到多个对象的副本。 
  • 对象传输
  通过序列化,将对象转化字节流后,可以通过网络发送给另外的Java程序。 


4、什么是流(Stream)

  Java是面向对象的编程语言,对象是对现实实体的抽象表述。所以Java API中流(Stream)是对一连串数据的抽象,同时定义了一些操作,write和read等。所以现实实体,只要包含数据和对数据的读写操作都可以表示为流。OutputStream类和InputStream类,是2个抽象类,分别对应输出、输入流,所有其它流对象,都是其子类。 
  比如文件,文件本质是保存在存储设备中的一连串数据,在Java API中抽象为FileOutputStream类和FileInputStream类,文件的读写可以通过对相应流的读写实现的。 
  比如控制台中命令和结果的输入输出,键盘的输入是一串数据,程序的输出是一串数据,所以在Java API中也被抽象为流对象。控制台输入由System.in对象体现,System.in是类型为InputStream的对象。控制台输出由System.out对象体现,System.out是类型为PrintStream的对象。 
  由于文件和控制台输入输出都和操作系统有关,所以文件流和控制台流对象最终都是由Java虚拟机创建的。 
  ByteArrayOutputStream、ByteArrayInputStream,是完全不依赖Java虚拟机的流对象,其完全是对一个byte[]数组的抽象。因为byte[]数组也是一连串数据,byte[]数组支持读写功能,所以完全可以抽象为流对象,这可以从这两个类的源代码中看出。 


4、使用序列化功能

  在Java API中,对象序列化接口主要由两个类提供:ObjectOutputStream,ObjectInputStream。 
  为了满足保存到文件、内存、通过网络传输等不同需求,对象序列化后保存在流对象中。提供不同的流对象时,序列化后保存在相应流对象中。比如提供FileOutputStream和FileInputStream,就保存在文件中;提供ByteArrayOutputStream、ByteArrayInputStream,就保存在内存中。 
  由于Java API已经提供了实现序列化需要的相关代码,所以大部分情况下,使用序列化很简单。例如: 
  保存对象: 
//创建一个流对象,比如文件输出流对象
FileOutputStream underlyingStream = new FileOutputStream("C:\\temp\\test");
//用刚才的文件流,创建一个对象序列化输出流
ObjectOutputStream serializer = new ObjectOutputStream(underlyingStream);
//使用该流的输出函数,将对象序列化后保存到文件流中,也就是保存到了对应文件中。
serializer.writeObject(serializableObject);


  读取对象,操作完全与保存是一一对应: 
//创建一个流对象,比如文件输入流对象
FileInputStream underlyingStream = new FileInputStream("C:\\temp\\test");
//用刚才的文件流,创建一个对象序列化输入流
ObjectInputStream deserializer = new ObjectInputStream(underlyingStream);
//使用该流的输入函数,将文件中保存的对象读取到内存中,并创建相应对象。
Object deserializedObject = deserializer.readObject(  );



5、什么样的类可以序列化

  不是所有的类都有序列化的必要,比如Thread类等,这些类中并没有必要保存的信息。这也是序列化没有成为Java内部功能的原因之一。所以,如果某个类需要序列化功能,类的定义中必须实现Serializable或者Externalizable接口。 
  比如Java API中的Character类: 
public final
class Character implements java.io.Serializable, Comparable<Character>





6、进一步的内容

  进一步的内容比如transient关键字、自定义序列化机制、序列化版本控制等,请参考以下文章:

  Java RMI  Chapter 10  Serialization  By William Grosso 
  http://oreilly.com/catalog/javarmi/chapter/ch10.html 


  Discover the secrets of the Java Serialization API   by Todd Greanier 
  http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html

感谢http://my.oschina.net/u/1382972/blog/170148




Java 的序列化 (Serialization) 教程

Java提供一种机制叫做序列化,通过有序的格式或者字节序列持久化java对象,其中包含对象的数据,还有对象的类型,和保存在对象中的数据类型。 所以,如果我们已经序列化了一个对象,那么它可以被读取并...
  • woailuo453786790
  • woailuo453786790
  • 2015年10月12日 15:51
  • 513

初探Java序列化(Serialization)

Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化Deserialization是一种将这些字节重建成一个对象的过程。【字节流的来回转换】 Java中,一切都是对象,在...
  • tiwerbao
  • tiwerbao
  • 2015年02月26日 22:24
  • 1727

C++Boost序列化(Serialization)库教程

一个非常简单的情形 非侵入的版本 可序列化的成员 派生类 指针 数组 STL容器 类的版本 把serialize拆分成save/load 档案 输出档案(archive)类似于输出数据流(stream...
  • fanyun_01
  • fanyun_01
  • 2016年09月30日 09:22
  • 1627

序列化(Serialization)一个对象

1. 序列化的概念         序列化: 将数据结构或对象转换成二进制串的过程,简单理解就是将对象转换为容易传输的格式的过程。 2. 序列化的作用    序列化是为了保存内存中各种对象的状态,并且...
  • xby_869151205
  • xby_869151205
  • 2016年08月06日 17:19
  • 504

序列化、持久化、marshalling

序列化、持久化、marshalling三者要解决的问题。
  • tyger
  • tyger
  • 2011年01月04日 18:18
  • 1784

畅游C++ Boost Serialization 序列化

畅游C++ Boost Serialization 序列化。使用案例详细了解Boost::Serialization存储C++对象。...
  • qq2399431200
  • qq2399431200
  • 2015年05月10日 17:27
  • 2063

怎样用boost::serialization去序列化派生模板类

本篇是boost::serialization 用基类指针转存派生类(错误多多,一波三折)的姊妹篇,这里只不过做一个总结。 先来看一个基类 class base_class { public: ba...
  • yanziguilai
  • yanziguilai
  • 2014年05月03日 17:30
  • 1502

深度序列化的一种解决方案

说明:在unity3d中自己定义的scriptobject中使用了一个可以序列化的类,希望可以在界面上显示,但这个类的一个树型结构,其中包含了同类型的列表。这种情况下,利用unity自己的序列化方式虽...
  • tankerhunter
  • tankerhunter
  • 2017年06月15日 20:15
  • 382

Dubbo中使用高效的Java序列化(Kryo和FST)

序列化漫谈 dubbo RPC是dubbo体系中最核心的一种高性能、高吞吐量的远程调用方式,我喜欢称之为多路复用的TCP长连接调用,简单的说: 长连接:避免了每次调用新建TCP连接,提...
  • moonpure
  • moonpure
  • 2016年11月15日 19:28
  • 12310

Python学习笔记 --- 序列化Serialize 和 反序列化Deserialize

Python学习笔记 --- 序列化Serialize 和 反序列化Deserialize
  • u012965373
  • u012965373
  • 2017年04月07日 19:06
  • 2607
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JAVA之序列化(Serialization)的理解
举报原因:
原因补充:

(最多只允许输入30个字)