JAVA序列化

来源:互联网 发布:linux中怎么创建文件 编辑:程序博客网 时间:2024/06/05 10:38

参考文献:

http://www.cnblogs.com/olivelv/p/5200935.html

http://blog.csdn.net/wangloveall/article/details/7992448/

1.概述

JAVA序列化:把JAVA对象转化为字节序列   

JAVA反序列化 :把字节序列转化为JAVA对象

两个进程进行通讯时,发送方把JAVA对象转化为字节序列,接收方把字节序列恢复JAVA对象

Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)

2.序列化好处

实现了数据的持久化,通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里

利用序列化实现远程通信,即在网络上传送对象的字节序列。

3.实现

⑴JDK序列化的API

java.io.ObjectOutputStream:表示对象输出流

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

java.io.ObjectInputStream:表示对象输入流

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

实现序列化的要求

只有实现了SerializableExternalizable接口的类的对象才能被序列化,否则抛出异常。

实现Java对象序列化与反序列化的方法

①方法一:若Student类仅仅实现了Serializable接口,则可以按照以下方式进行序列化和反序列化
ObjectOutputStream采用默认的序列化方式,对Student对象的非transient的实例变量进行序列化。
ObjcetInputStream采用默认的反序列化方式,对Student对象的非transient的实例变量进行反序列化。
一个对象只要实现了Serializable接口,该对象就可以被序列化。然而在实际开发过程中,常常会遇到这样的问题,该类有些属性需要序列化,其他属性不需要被序列化。例如一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及序列化)中被传输,这些信息对应的变量就可以加上transient关键字,这样变量的生命周期仅存在于调用者的内存中而不会被写到磁盘里持久化。
②方法二:若Student类仅仅实现了Serializable接口,并且还定义了readObject(ObjectInputStream in)和writeObject(ObjectOutputSteam out),则采用以下方式进行序列化与反序列化。

ObjectOutputStream调用Student对象的writeObject(ObjectOutputStream out)的方法进行序列化。
ObjectInputStream会调用Student对象的readObject(ObjectInputStream in)的方法进行反序列化。
③方法三:若Student类实现了Externalnalizable接口,且Student类必须实现readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法,则按照以下方式进行序列化与反序列化。
ObjectOutputStream调用Student对象的writeExternal(ObjectOutput out))的方法进行序列化。
ObjectInputStream会调用Student对象的readExternal(ObjectInput in)的方法进行反序列化。

4.具体步骤

序列化步骤:

步骤一:创建一个对象输出流,它可以包装一个其它类型的目标输出流,如文件输出流:
ObjectOutputStream out = new ObjectOutputStream(new fileOutputStream(“D:\\objectfile.obj”));
步骤二:通过对象输出流的writeObject()方法写对象:
out.writeObject(“Hello”);
out.writeObject(new Date());
JDK类库中反序列化的步骤
步骤一:创建一个对象输入流,它可以包装一个其它类型输入流,如文件输入流:
ObjectInputStream in = new ObjectInputStream(new fileInputStream(“D:\\objectfile.obj”));
步骤二:通过对象输出流的readObject()方法读取对象:
String obj1 = (String)in.readObject();
Date obj2 = (Date)in.readObject();
说明:为了正确读取数据,完成反序列化,必须保证向对象输出流写对象的顺序与从对象输入流中读对象的顺序一致。

5.代码

package com.study;import java.io.Serializable;public class student implements Serializable { private String name;   private transient char sex;   private int year;   private transient  double gpa;     public student()   {     }   public student(String name,char sex,int year,double gpa)   {    this.name = name;    this.sex = sex;    this.year = year;    this.gpa = gpa;   }     public void setName(String name)   {    this.name = name;   }     public void setSex(char sex)   {    this.sex = sex;   }     public void setYear(int year)   {    this.year = year;   }     public void setGpa(double gpa)   {    this.gpa = gpa;   }     public String getName()   {    return this.name;   }      public char getSex()   {    return this.sex;   }     public int getYear()   {    return this.year;   }     public double getGpa()   {    return this.gpa;   }  }
package com.study;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;public class UseStudent {public static void main(String[] args)   {    student st = new student("Tom",'M',20,3.6);    File file = new File("C:\\tmp.txt");    try    {     file.createNewFile();    }    catch(IOException e)    {     e.printStackTrace();    }    try    {     //Student对象序列化过程     FileOutputStream fos = new FileOutputStream(file);     ObjectOutputStream oos = new ObjectOutputStream(fos);     oos.writeObject(st);     oos.flush();     oos.close();     fos.close();       //Student对象反序列化过程     FileInputStream fis = new FileInputStream(file);     ObjectInputStream ois = new ObjectInputStream(fis);     student st1 = (student) ois.readObject();     System.out.println("name = " + st1.getName());     System.out.println("sex = " + st1.getSex());     System.out.println("year = " + st1.getYear());     System.out.println("gpa = " + st1.getGpa());     ois.close();     fis.close();    }    catch(ClassNotFoundException e)    {     e.printStackTrace();    }    catch (IOException e)    {     e.printStackTrace();    }                }  }
输出:

name = Tom
sex = 
year = 20
gpa = 0.0