一直搞不懂java序列化和反序列化,今天来整理一发。
为什么需要序列化和反序列化?
我们知道,在两个Java进程中进行远程通信时,可以互相发送各种类型的数据,包括文本、图片、音频、视频等,而这些数据都会以二进制序列的形式在网络上传送。那么当两个Java进程进行通信时,能否实现进程间的对象传送呢?答案是可以的。如何做到呢?这就需要java的序列化和反序列化了。换句话说,一方面,发送方需要把这个对象转换为字节序列,然后在网络上传送;另一方面,接收方需要从字节序列中恢复出Java对象。基本原理和网络通信时一致的,通过特殊的编码方式:写入数据将对象及其内部数据编码,存在在数组或者文件里面然后发送到目的地后,在进行解码,读出数据。到此显示出来为我们所用即可。
Java序列化优点:
1)实现数据的持久化,通过序列化可以把数据永久地保存在硬盘上;
2)利用序列化实现远程通信,即在网络上传送对象的字节序列。
序列化与反序列化
序列化(Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。一般将一个对象存储至一个存储媒介,例如档案或是记忆体缓冲等。在网络传输过程中,可以是字节或者xml等格式。而字节的或xml编码格式可以还原完全相等的对象。这个相反的过程又称为反序列化。
Java对象的序列化和反序列化
在Java中,可以通过多种方式创建对象,并且只要对象没有被回收我们都可以复用该对象。但是,我们创建出来的这些Java对象都是存在于JVM的堆内存中的。只有JVM处于运行状态的时候,这些对象才有可能存在。一旦JVM停止运行,这些对象的状态也就随之而丢失了。
但是在真实的应用场景中,我们需要将这些对象持久化下来,并且能够在需要的时候把对象重新读取出来。Java的对象序列化可以帮我们实现该功能。
对象序列化机制(Object Serilization)是Java语言内建的一种对象持久化方式,通过对象序列化,可以把对象的状态保存为字节数组,并且可以在有需要的时候将这个字节数组通过反序列化的方式再转换为对象。对象序列化可以很容易的在JVM中的活动对象和字节数组(流)之间进行转换。
在Java中,对象的序列化与反序列化被广泛应用到RMI(远程方法调用)及网络传输中。
相关接口与类
Java为了方便开发人员将Java对象进行序列化及反序列化提供一套方便的API来支持。其中包括以下接口和类:
java.io.Serializable
java.io.Externalizable
ObjectOutput
ObjectInput
ObjectOutputStream
ObjectInputStream
Serializable接口
类通过实现java.io.Serializable接口已启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。(该接口并没有方法和字段,为什么只有实现了该类接口的类的对象才能被序列化呢?)