`
renyanwei
  • 浏览: 70052 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

JAVA语言序列化和反序列化一目了然(一)认识

阅读更多

在JAVA中,一个大的应用程序需要保存很多对象的时候,由于虚拟机内存有限,(资源宝贵啊 )有时不可能所有有用的对象都放到内存中,因此,需要将不常用的对象暂时持久化的文件中,当需要这个对象时,再从文件把对象恢复到内存中,这就是所谓对象的序列化和反序列化。本文讲实现如何将对象序列化到文件,然后再从文件反序列化到对象,你会发现其实特别简单

 

先看一下对象的序列化和反序列化的关键是什么

1,首先被序列化的对象必须实现 java.io.Serializable 接口,咳~~咳~~,其实这个接口没定义任何方法

 

2,序列化时,需要用到对象输出流ObjectOutputStream ,然后通过文件输出流构造 ObjectOutputStream 对象调用writeObject写入到文件

 

3,反之,反序列化时用到对象输入流ObjectIntputStream,  然后通过文件输出流构造 ObjectIntputStream对象调用readObject加载到内存,注意,是返回万能Object类型

 

4,注意:序列化时transient变量(这个关键字的作用就是告知JAVA我不可以被序列化)和静态变量不会被序列化(关于静态变量不会序列化保留意见,本实例先不用静态变量)

 

5,也是最应该注意的,如果你先序列化对象A后序列化B,那么在反序列化的时候一定记着JAVA规定先读到的对象是先被序列化的对象,不要先接收对象B,那样会报错

 

好了,现在我们做一个实例,我们现在要序列化一个会员对象到文件里,然后再把它读出来

先创建会员类

import java.io.*;
import java.util.*;

//一定要实现Serializable接口才能被序列化
public class UserInfo implements Serializable {
	public String userName;
	public String userPass;
	//注意,userAge变量前面的transient
	public transient int userAge;

	public UserInfo(){
	}

	public UserInfo(String username,String userpass,int userage){
		this.userName=username;
		this.userPass=userpass;
		this.userAge=userage;
	}

	public String toString(){
		return "用户名: "+this.userName+";密码:"+this.userPass+
			";年龄:"+this.userAge;
	}
}

 接着我们开始写如何序列化和反序列化,初学认真看哦

import java.io.*;
import java.util.*;
public class Test {

	//序列化对象到文件
	public static void serialize(String fileName){
		try
		{
			//创建一个对象输出流,讲对象输出到文件
			ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream(fileName));

			out.writeObject("序列化日期是:");	 //序列化一个字符串到文件

			out.writeObject(new Date());	//序列化一个当前日期对象到文件

			UserInfo user=new UserInfo("renyanwei","888888",20);
			out.writeObject(user);	//序列化一个会员对象

			out.close();
		}
		catch (Exception x)
		{
			System.out.println(x.toString());
		}
		
	}
	//从文件反序列化到对象
	public static void deserialize(String fileName){
		try
		{
			//创建一个对象输入流,从文件读取对象
			ObjectInputStream in=new ObjectInputStream(new FileInputStream(fileName));

			//注意读对象时必须按照序列化对象顺序读,否则会出错
			//读取字符串
			String today=(String)(in.readObject());
			System.out.println(today);

			//读取日期对象
			Date date=(Date)(in.readObject());
			System.out.println(date.toString());

			//读取UserInfo对象并调用它的toString()方法
			UserInfo user=(UserInfo)(in.readObject());			
			System.out.println(user.toString());

			in.close();
		}
		catch (Exception x)
		{
			System.out.println(x.toString());
		}
		
	}

	public static void main(String[] args) {	
		serialize("D:\\test.txt");
		System.out.println("序列化完毕");

		deserialize("D:\\test.txt");
		System.out.println("反序列化完毕");
	}

}

运行结果:


序列化完毕
今天是:
Thu Oct 23 18:31:11 CST 2008
用户名: renyanwei;密码:888888;年龄:0
反序列化完毕

我们看代码总结一下,serialize方法实现了对象的序列化功能,讲对象序列化到文件,使用了文件的输出流ObjectOutputStream 的writerObject方法一次写入一个对象,对象在文件中按写入顺序存储。

deserialize方法实现反序列化,从文件将对象反序列化到内存,使用了ObjectIntputStream 的readObject方法,因为序列化对象是按照写入顺序存储的,所以在反序列化时必须按照写入顺序读取

大家看了结果就应该知道了,标明transit的实例变量是没被序列化进去的 ,呵呵

 

其实序列化的意义不止如此,不但可以将对象放到文件流,还可以放到网络流里,比如我们做的Socket程序,你不但可以发送给对方一行消息,还可以发送过去一个对象,我估计QQ就不止是把我们的消息发送到对方,应该是一个对象,里面包含了发送者的信息什么的。呵呵 有兴趣的可以做一下哈

 

 

 

 

9
1
分享到:
评论
6 楼 彼岸花er 2012-02-18  
phoenix007 写道
不错,学习了。

+1收藏着
5 楼 donald8219 2010-03-26  
写得很好,谢谢了,正好用着。
4 楼 phoenix007 2008-11-04  
不错,学习了。
3 楼 daoyongyu 2008-10-30  
呵呵,写得不错。比较适合初学者。
2 楼 renyanwei 2008-10-24  
LinuxFans 写道

写得很好,
记得好像还要添加序列化id吧?
如:private static final long serialVersionUID = 1L;

恩 那个回头再讲,先学习简单的入门知识
1 楼 LinuxFans 2008-10-24  
写得很好,
记得好像还要添加序列化id吧?
如:private static final long serialVersionUID = 1L;

相关推荐

Global site tag (gtag.js) - Google Analytics