java的序列化

来源:互联网 发布:linux下启动jenkins 编辑:程序博客网 时间:2024/04/30 02:20

一、什么是序列化,为什么要序列化,序列化解决了什么问题

二、怎样实现java的序列化以及重点

三、序列化的识别


一、什么是序列化,为什么要实现java的序列化

  0、序列化:将对象数据直接转换成字节流数据保存起来,并且在以后恢复成对象的过程

  1、存储对象的状态,直接将对象的状态保存到文件里面,eg:保存游戏人物的状态

  2、为了解决当存储一个对象的时候,如果存在另外的一个对象的引用时的存储问题


二、怎么实现java序列化以及重点

 1、具体实现(让类实现Serializable接口)

package com.chenrui.serializable1;import java.io.Serializable;/** * 游戏里面的任务状态类(headFirst java 上面的例子) * */public class GameCharacter implements Serializable{private int power;//血量private String name;//人物的姓名private String type;//任务的种类private String[] weapons;//武器public GameCharacter(int power,String name,String type,String[] weapons) {super();this.power = power;this.type = type;this.weapons = weapons;this.name = name;}@Overridepublic String toString() {StringBuffer sb = new StringBuffer();sb.append("name is "+name+" ");sb.append("power is "+this.power+" ");sb.append("type is "+this.type+" ");sb.append("weapon is ");for(String weapon : this.weapons) {sb.append(weapon+" ");}return sb.toString();}}
2、测试类

package com.chenrui.serializable1;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;/** * 游戏人物状态保持的模拟 * */public class GameSaveTest {public static void main(String[] args) throws ClassNotFoundException {//任务的生成模拟GameCharacter jintian = new GameCharacter(100,"景天","剑士",new String[]{"长剑","盾牌","轻灵战靴"});GameCharacter lixiaoyao = new GameCharacter(100,"李逍遥","剑士",new String[]{"天剑","多兰之盾","急行战靴"});GameCharacter zhaolinger = new GameCharacter(100,"赵灵儿","法师",new String[]{"天蛇杖","兰顿","水银战靴"});//这里是战斗的代码//现在玩家要退出,这里是保存他们的数据的代码,将对象保存起来try {FileOutputStream fos = new FileOutputStream("仙剑save.txt");//生成一个节点流ObjectOutputStream oos = new ObjectOutputStream(fos);//生成ObjectOutputStream过滤流oos.writeObject(jintian);//将数据写入ObjectOutPutStream;oos.writeObject(lixiaoyao);oos.writeObject(zhaolinger);oos.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}//这个是退出游戏与重新登陆时的状态jintian = null;zhaolinger = null;lixiaoyao = null;//这里的就是重写读取数据,获得保存之前的状态(解序列化)try {FileInputStream fis = new FileInputStream("仙剑save.txt");ObjectInputStream ois;ois = new ObjectInputStream(fis);jintian = (GameCharacter)ois.readObject();lixiaoyao = (GameCharacter)ois.readObject();zhaolinger = (GameCharacter)ois.readObject();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}//接下来就是输出测试System.out.println(jintian.toString());System.out.println(lixiaoyao.toString());System.out.println(zhaolinger.toString());}}
3、过程简析:

(1)要保存对象所对应的类实现Serializable接口

 (2)将对象保存的过程

    1、生成一个节点输出流 

            2、生成一个ObjectOutputStream,他链接到上面的节点流

            3、写对象       

4、用到的接口与类

   (1)Serializable接口

    (2)ObjectOutStream类以及里面的writeObject方法,这个类实现了ObjectOutput接口


5、序列化的注意事项:

      (1)在序列化时,static类型的变量时不会别保存的。因为这个变量时属于类的,而不是属于当个对象的

      (2)在序列化时,如果希望某些变量不被保存,可以再声明的时候加上transient关键字,


6、重点

    (1)在对象被序列化时,被该对象引用的实例变量也会被序列化,且所有被引用的对象也会被序列化(前提示被引用的对象所对应的类都实现了Serializable接口),如果有

              俩个引用指向的是同一个对象,这个时候只保存一个对象。

    (2)在序列化的过程中,ObjectOutStream的作用是把对象转化为可以写入串流的数据,FileOutputStream等节点流负责将数据写入文件。


7、解序列化

   (1)创建FileInputStream

   (2)创建ObjectInputStream

   (3)读取对象,使用readObject()方法,这里是根据写入的顺序进行读取

 (4)转换对象类型

 (5)关闭ObjectInputStream;

深入解析:

   (1)把对象从Stream读取出来

    (2)jvm通过存储的信息判断对象的类型

     (3)jvm尝试寻找和加载对象的类,如果无法找到或者是无法加载,则会抛出异常

     (4)新的对象被配置到堆上,但是构造函数不会执行。 

      (5)对象的实例变量会被还原成序列化时点的状态,transient变量会被赋值为null,

   

三、序列化的识别

   1、如果对象被序列化后,要解序列化,必须保证在解序列化之前没有进行损害序列化的修改。

        2、serialVersionUID:当对象被序列化的时候,该对象将会获得一个根据类的结构信息而生成的seriaVersionUID,java尝试要还原对象的时候,它会比对对象与jvm上类的serialVersionUID.如果版本不相同,将会抛出异常。

   

0 0