Cyh的博客

Email:kissyan4916@163.com
posts - 26, comments - 19, trackbacks - 0, articles - 220

序列化和反序列化对象

Posted on 2009-05-24 22:18 啥都写点 阅读(216) 评论(0)  编辑  收藏 所属分类: J2SE
   一个大的应用程序需要使用很多的对象,由于虚拟机内存有限,有时不可能将所有有用的对象都放在内存中,因此,需要将不常用的对象暂时持久化到文件中,当需要使用该对象时,再从文件中把对象恢复到内存,这就是对象的序列化和反序列化。

关键技术:
  • 需要被序列化的对象必须实现java.io.Serializable接口,尽管该接口没有定义任何方法。
  • 对象输出流ObjectOutputStream可以将对象写入到流中,通过文件输出流可以构造ObjectOutputStream对象。写对象到文件时调用writeObject方法。
  • 对象输入流ObjectInputSteam可以从流中读取对象到内存,通过文件输入流可以构造ObjectInputStream对象。从文件读对象到内存时调用readObject方法,返回一个Object对象。
  • 序列化时,transient变量和类变量(静态变量)不会被序列化。
  • 序列化时,对象按照writeObject方法的调用顺序存储在文件中,先被序列化的对象的数据在文件的前面,后被序列化的对象的数据在文件的后面。因此,在反序列化时,先读到得对象肯定是先被序列化的对象。
 
package book.io;


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;
/**
 * 序列化和反序列化对象
 
*/
public class SerializeObject {
    
//    一个内部类,用于被序列化和反序列化。
    
//一定要实现Serializable才能够被序列化和反序列化。
    static class MyClass implements Serializable{
        
//一般的实例变量会被序列化和反序列化
        private int a,b;
        
//transient实例变量 不会 被序列化和反序列化
        private transient int c; 
        
// 类变量 不会 被序列化和反序列化
        private static int d;
        
public MyClass(){
        }
        
public MyClass(int a, int b, int c, int d){
            
this.a = a;
            
this.b = b;
            
this.c = c;
            MyClass.d 
= d;
        }
        
public String toString(){
            
return this.a + "  " + this.b + "  " + this.c + "  " + MyClass.d;
        }
    }

    
/**
     * 序列化对象到文件
     
*/
    
public static void serialize(String fileName) throws Exception{
        
//创建一个对象输出流,将对象输出到文件
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(fileName));
        
//序列化一个字符串对象到文件
        out.writeObject("Today:");
        
//序列化当前日期对象到文件
        out.writeObject(new Date());
        
//序列化一个MyClass对象
        MyClass my1 = new MyClass(5678);
        out.writeObject(my1);
        out.close();
    }
    
/**
     * 从文件反序列化到对象
     
*/
    
public static void deserialize(String fileName) throws Exception{
        
//创建一个对象输入流,从文件读取对象
        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());
        
//读MyClass对象,并调用它的add方法。
        MyClass my1 = (MyClass)(in.readObject());
        System.out.println(my1.toString());
        in.close();
        
//当恢复对象的时候,对象中的所有域被自动的恢复。如果不希望某个域被序列化,可以在它前面
        
//加上transient关键字,例如下面的代码:transient int noSer = 0;
        
//类似的,如果类中的某个域为静态,它不会被序列化。
    }
    
/**
     * 
@param args
     
*/
    
public static void main(String[] args) throws Exception{
        String fileName 
= "c:/temp/MyClass.ser";
        SerializeObject.serialize(fileName);
        
//注释掉第二行,只运行下面一行,将会发现输出不同
        SerializeObject.deserialize(fileName);
    }
}

运行结果:

Today:
Sun Jul 30 11:49:38 CST 2006
5   6   0   8



                                                                                                       --    学海无涯
        


只有注册用户登录后才能发表评论。


网站导航: