串行化

串行化

串行化(serialization)是指将一个对象的当前状态转换成字节流(a stream of bytes)的过程,而反串行化(deserialization)则指串行化过程的逆过程,将字节流转换成一个对象,打回原形
一、串行化的意义:
1:解决Web应用程序的无状态弊端
一旦将某一对象串行化,得到的字节可以存储在文件、数据库,或内存中—— 只要是可以存储的任何地方。需要恢复对象时,仅仅只需从它存储的位置反串行化即可。对象固有的这种特性对于无状态的Web应用程序是非常重要的,因为它允许重要的状态信息可以在用户请求之间保留。
2:应用程序边界之间传递对象
串行化也允许对象在应用程序边界之间传递,编程人员可以将描述对象状态的字节流在网络上传递,并在另一端反串行化成一个匹配的对象。从本质上讲,串行化允许对象以“数值”的方式传递给另一个应用程序。
二:串行化对象
在java中串行化对象必须:
1、该对象的类必须实现Serializable接口
2、该对象的串行化成员必须是非静态成员变量,即不能保存任何的成员方法和静态的成员变量,而且串行化保存的只是变量的值,对于变量的任何修饰符,都不能保存。而对于某些类型的对象,其状态是瞬时的,这样的对象是无法保存其状态的,例如一个Thread对象,或一个FileInputStream对象,对于这些字段,我们必须用transient关键字标明 。
注:保存任何的成员方法和静态的成员变量没有任何的意义,因为,对象的类已经完整的保存了他们,如果再串行化没有任何意义
3、要串行化一个对象,必须与一定的对象输入/输出流联系起来,通过对象输出流将对象状态保存下来,再通过对象输入流将对象状态恢复。

实现远程方法调用(Remote Method Invation,RMI)也需要串行化。远程方法调用允许在一台机器上的Java对象调用在另外一台机器上Java对象的方法。可以将对象作为参数提供给远程方法,发送机器串行化对象并进行传递,接受机器反串行化对象

Serializable接口

   只有实现了Serializable接口的类才能够通过串行化进行保存和恢复。Serializable接口没有定义成员,这是简单的用于指示类可以被串行化。如果一个类是可以串行化的,那么这个类的所有子类也是可串行化的。

   声明为transient的变量不能通过串行化进行保存。此外也不能保存static变量。

Externailzable接口

   Java对串行化和反串行化功能进行了精心设计,从而使得许多保存和恢复对象状态的工作都可以自动运行。然而在有些情况下,程序员可能需要控制整个过程。例如,可能希望使用压缩和加密技术。Externailzable接口就是针对这些情况而设计的,此接口定义了下面两个构造方法:

 void readExternal(ObjectInput instream)

                throws IOException,ClassNotFoundException

 void writeExternal(ObjectOutput outstream)

                throws IOException

在这两个方法中,instream是从中读取对象的字节流,outstream是将对象写入其中的字节流

transient简介

  众所周知一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了许多便利,我们可以不必关心具体序列化的过程,只要这个类实现了Serilizable接口,这个类的所有属性与 方法都会自动序列化。

  然而在实际开发过程中,我们常常会遇到这样的问题,这个类的有些属性需要序列化,而其他属性不需要被序列化,当然你可以让这个类来实现Externalizable接口,这个接口是Serilizable的子接口,但你必须实现readExternal和writeExternal方法,你可以在这两个方法中实现具体属性的序列化和反序列化操作。然而这就意味着你必须在这两个方法中手工编写额外的代码来进行具体属性的序列化。Java的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化属性的时候,这个属性就不会序列化指定的目的地中

ObjectOutput接口

  ObjectOutput接口扩展了DataOutput和AutoCloseable接口,并且支持对象串行化。如下显示此接口的方法。特别注意writeObject,该方法用于串行化对象,如果遇到错误会抛出IOException异常

ObjectOutputStream类

  ObjectOutputStream类扩展了OutputStream类并实现了ObjectOutput接口,负责将对象写入到流中。该类的一个构造函数如下所示:

ObjectOutputStream(OutputStream outstream)  throws IOException

此类定义的一些方法如下所示:

串行化_第1张图片

ObjectInput接口

   ObjectInput接口扩展了DataOutput和AutoCloseable接口,并定义了如下显示的方法。ObjectInput接口支持对象串行化。应特别注意readObject()方法,该方法用于反串行化对象。如果遇到错误,会抛出IOException

异常,定义的具体方法如下所示:

串行化_第2张图片

ObjectInputStream类

   ObjectInputStream类扩展了InputStream类并实现了ObjectInput接口。ObjectInputStream负责从流中读取对象,该类的一个构造函数如下所示:

ObjectInputStream(InputStream inStream)  throws IOException

    参数inStream是从中读取串行化对象的输入流。关闭ObjectInputStream对象会关闭inStream指定的底层流

    如下显示一些此类的具体用法。readObject()方法还能抛出ClassNotFoundException异常。

串行化_第3张图片

      串行化示例

  下面的程序演示了如何使用对象串行化和反串行化。该程序首先实例化MyClass类的一个对象。这个对象具有3个实例变量,分别是String、int、和double类型。String与int类型是要保存和恢复的信息。

  创建一个指向“serial”文件的FileInputStream对象,并为该文件创建一个ObjectOutputStream对象。然后使用ObjectOutputStream的writeObject()方法串行化对象。接下来刷新并关闭对象输出流。

  然后创建一个指向“serial”文件的FileInputStream对象,并为该文件流创建一个ObjectInputStream对象。然后使用ObjectInputStream的readObject()方法反串行化对象。接下来关闭对象输入流。

  注意MyClass类实现了Serializable接口。否则会抛出NotSerializableException异常。如果尝试将一些MyClass实例变量声明为transient以实验该程序,那么在串行化期间不会保存这些数据。

import java.io.*;

class MyClass implements Serializable{
	String s;
	int i;
	 transient double d;
	
	public MyClass(String s,int i,double d){
		this.s=s;
		this.i=i;
		this.d=d;
	}
	public String toString(){
		return "s="+s+"; i="+i+"; d="+d;
	}
}

class SerializarionDemo {
public static void main(String[] args){
	try(ObjectOutputStream objoStrm=new ObjectOutputStream(new FileOutputStream("c:serial.txt"))){
		MyClass object1=new MyClass("Hello!你好",-7,2.7e10);
		System.out.println("object1: "+object1);
		
		objoStrm.writeObject(object1);
	}catch(IOException e){
		System.out.println("Exception during serialiation: "+e);
	}
	
	try(ObjectInputStream objiStrm=new ObjectInputStream(new FileInputStream("c:serial.txt"))){
		MyClass object2=(MyClass)objiStrm.readObject();
		System.out.println("object2: "+object2);
	}catch(Exception e){
		System.out.println("Exception deserialization: "+e);
	}
}
}


结果输出如下:

串行化_第4张图片

你可能感兴趣的:(串行化)