java的序列化

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

二、怎样实现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;
	}
	
	@Override
	public 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 block
			e.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 block
			e.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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值