现在的位置: 首页 > 综合 > 正文

Java中的序列化

2013年08月06日 ⁄ 综合 ⁄ 共 7342字 ⁄ 字号 评论关闭

Java中的序列化

一个类要想被序列化,就行必须实现java.io.Serializable接口。虽然这个接口中没有任何方法,就如同之前的cloneable接口一样。实现了这个接口之后,就表示这个类具有被序列化的能力。

一、先让我们实现一个具有序列化能力的类:

import java.io.*; 
/** 
 * 实现具有序列化能力的类 
 * */
public class SerializableDemo implements Serializable{ 
    public SerializableDemo(){ 
          
    } 
    public SerializableDemo(String name, int age){ 
        this.name=name; 
        this.age=age; 
    } 
    @Override
    public String toString(){ 
        return "姓名:"+name+"  年龄:"+age; 
    } 
    private String name; 
    private int age; 
}

 

二、使用ObjectOutputStream输出序列化后的内容:

public class ObjectOutputStreamDemo{ 
    public static void main(String[] args) throws IOException{ 
        File file = new File("d:" + File.separator + "hello.txt"); 
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream( 
                file)); 
        oos.writeObject(new Person("rollen", 20)); 
        oos.close(); 
    } 
}

 

【运行结果】:

当我们查看产生的hello.txt的时候,看到的是乱码,呵呵。因为是二进制文件。

 

三、使用ObjectInputStream反序列化该类型

import java.io.File; 
import java.io.FileInputStream; 
import java.io.ObjectInputStream; 
  
/** 
 * ObjectInputStream示范 
 * */
public class ObjectInputStreamDemo{ 
    public static void main(String[] args) throws Exception{ 
        File file = new File("d:" + File.separator + "hello.txt"); 
        ObjectInputStream input = new ObjectInputStream(new FileInputStream( 
                file)); 
        Object obj = input.readObject(); 
        input.close(); 
        System.out.println(obj); 
    } 
}

【运行结果】

姓名:rollen 
年龄:20

 

四、使用Externalizable接口来自定义序列化

Serializable接口声明的类的对象的属性都将被序列化,但是如果想自定义序列化的内容的时候,就需要实现Externalizable接口。使用Externalizable接口可以控制序列化哪些属性,而不序列化哪些属性。

当一个类要使用Externalizable这个接口的时候,这个类中必须要有一个无参的构造函数,如果没有的话,在构造的时候会产生异常,这是因为在反序列话的时候会默认调用无参的构造函数。

现在我们来演示一下序列化和反序列话:

import java.io.*;    
import java.util.*;    
   
//本程序通???Externalizable接口控制?象序列化和反序列    
public class UserInfo implements Externalizable {    
    public String userName;    
    public String userPass;    
    public int userAge;    
   
    public UserInfo(){    
    }    
   
    public UserInfo(String username,String userpass,int userage){    
        this.userName=username;    
        this.userPass=userpass;    
        this.userAge=userage;    
    }    
        
    //当序列化?象?,?方法自??用    
    public void writeExternal(ObjectOutput out) throws IOException{    
        System.out.println("?在?行序列化方法");    
        //可以在序列化?写非自身的?量    
        Date d=new Date();    
        out.writeObject(d);    
        //只序列化userName,userPass?量    
        out.writeObject(userName);    
        out.writeObject(userPass);    
    }    
   
    //当反序列化?象?,?方法自??用    
    public void readExternal(ObjectInput in) throws IOException,ClassNotFoundException{    
        System.out.println("?在?行反序列化方法");    
        Date d=(Date)in.readObject();    
        System.out.println(d);    
        this.userName=(String)in.readObject();    
        this.userPass=(String)in.readObject();    
    }    
   
    public String toString(){    
        return "用?名: "+this.userName+";密?:"+this.userPass+    
            ";年?:"+this.userAge;    
    }    
}

测试类

import java.io.ObjectOutputStream;    
import java.io.ObjectInputStream;    
import java.io.FileInputStream;    
import java.io.FileOutputStream;    
import java.util.Date;    
import java.lang.management.*;    
public class Test {    
   
   
   
    //序列化?象到文件    
    public static void serialize(String fileName){    
        try   
        {    
            //?建一个?象?出流,??象?出到文件    
            ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream(fileName));    
   
            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));    
   
            //?取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 22:18:12 CST 2008
用户名: renyanwei;密码:888888;年龄:0
反序列化完毕

 

五、使用transient来控制序列化的内容

Serializable接口实现的操作其实是吧一个对象中的全部属性进行序列化,当然也可以使用我们上使用是Externalizable接口以实现部分属性的序列化,但是这样的操作比较麻烦,

当我们使用Serializable接口实现序列化操作的时候,如果一个对象的某一个属性不想被序列化保存下来,那么我们可以使用transient关键字进行说明:

 

package IO; 
  
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.io.Serializable; 
  
/** 
 * 序列化和反序列化的操作 
 * */
public class serDemo{ 
    public static void main(String[] args) throws Exception{ 
        ser(); // 序列化 
        dser(); // 反序列话 
    } 
  
    public static void ser() throws Exception{ 
        File file = new File("d:" + File.separator + "hello.txt"); 
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream( 
                file)); 
        out.writeObject(new Person1("rollen", 20)); 
        out.close(); 
    } 
  
    public static void dser() throws Exception{ 
        File file = new File("d:" + File.separator + "hello.txt"); 
        ObjectInputStream input = new ObjectInputStream(new FileInputStream( 
                file)); 
        Object obj = input.readObject(); 
        input.close(); 
        System.out.println(obj); 
    } 
} 
  
class Person1 implements Serializable{ 
    public Person1(){ 
  
    } 
  
    public Person1(String name, int age){ 
        this.name = name; 
        this.age = age; 
    } 
  
    @Override
    public String toString(){ 
        return "姓名:" + name + "  年龄:" + age; 
    } 
  
    // 注意这里 
    private transient String name; 
    private int age; 
}

【运行结果】:

姓名:null 
年龄:20

 

六、数组的序列化

 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.io.Serializable; 
  
/** 
 * 序列化一组对象 
 * */
public class SerDemo1{ 
    public static void main(String[] args) throws Exception{ 
        Student[] stu = { new Student("hello", 20), new Student("world", 30), 
                new Student("rollen", 40) }; 
        ser(stu); 
        Object[] obj = dser(); 
        for(int i = 0; i < obj.length; ++i){ 
            Student s = (Student) obj[i]; 
            System.out.println(s); 
        } 
    } 
  
    // 序列化 
    public static void ser(Object[] obj) throws Exception{ 
        File file = new File("d:" + File.separator + "hello.txt"); 
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream( 
                file)); 
        out.writeObject(obj); 
        out.close(); 
    } 
  
    // 反序列化 
    public static Object[] dser() throws Exception{ 
        File file = new File("d:" + File.separator + "hello.txt"); 
        ObjectInputStream input = new ObjectInputStream(new FileInputStream( 
                file)); 
        Object[] obj = (Object[]) input.readObject(); 
        input.close(); 
        return obj; 
    } 
} 
  
class Student implements Serializable{ 
    public Student(){ 
  
    } 
  
    public Student(String name, int age){ 
        this.name = name; 
        this.age = age; 
    } 
  
    @Override
    public String toString(){ 
        return "姓名:  " + name + "  年龄:" + age; 
    } 
  
    private String name; 
    private int age; 
}

【运行结果】:

姓名:  hello 
年龄:20

姓名:  world 
年龄:30

姓名:  rollen 
年龄:40

 

七、把类型序列化为XML格式

序列化、反序列化为XML文件,我使用了XStream来序列化,需要引入xstream-1.3.1.jar包的支持,
http://xstream.codehaus.org/download.html  处可以下载jar,然后引入到Eclipse中的build path中。

public class Person implements Serializable{
    private String name;
    private int age;
    public Person(){
        
    }
    public Person(String str, int n){
        System.out.println("Inside Person's Constructor");
        name = str;
        age = n;
    }
    String getName(){
        return name;
    }
    int getAge(){
        return age;
    }
}

 

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import com.thoughtworks.xstream.*;

public class Serialize {
    public static void main(String[] args) {
        Serialize ser = new Serialize();
        ser.serializeToXml();
        ser.deSerializeFromXml();
    }
    
public void serializeToXml(){
        Person[] myPerson = new Person[2];
        myPerson[0] = new Person("Jay",24);
        myPerson[1] = new Person("Tom",23);
        
        XStream xstream = new XStream();  
        try {
            FileOutputStream fos = new FileOutputStream("E:\\workspace\\2010_03\\src\\myPerson.xml");
             xstream.toXML(myPerson,fos);
             } catch (FileNotFoundException ex) {
             ex.printStackTrace();
             }       
        System.out.println(xstream.toXML(myPerson));
    }
    public void deSerializeFromXml(){
         XStream xs = new XStream();
         Person[] myPerson = null;

         try {
         FileInputStream fis = new FileInputStream("E:\\workspace\\2010_03\\src\\myPerson.xml");
         myPerson=(Person[])xs.fromXML(fis);
         if (myPerson != null)
         {
             int len = myPerson.length;
             for (int i=0;i<len;i++)
             {
                 System.out.println(myPerson[i].getName());
                 System.out.println(myPerson[i].getAge()); 
             }

         }
         } catch (FileNotFoundException ex) {
         ex.printStackTrace();
         }
    }
}

 

【运行结果】:

Inside Person's Constructor
Inside Person's Constructor

Jay
24
Tom
23

 

输出的XML文件为:

<Person-array>
  <Person>
    <name>Jay</name>
    <age>24</age>
  </Person>
  <Person>
    <name>Tom</name>
    <age>23</age>
  </Person>
</Person-array>

 

 

 

 

 

 

 

 

抱歉!评论已关闭.