首页 > 代码库 > 序列化反序列化

序列化反序列化

对Java对象序列化的目的是持久化对象或者为RMI(远程方法调用)传递参数和返回值。

下面是一个序列化对象写入文件的例子:

----------------------------

 1 package utils;
 2 
 3 import java.io.File;
 4 import java.io.FileInputStream;
 5 import java.io.FileOutputStream;
 6 import java.io.IOException;
 7 import java.io.ObjectInputStream;
 8 import java.io.ObjectOutputStream;
 9 import java.io.Serializable;
10 
11 //同样需要实现Serializable
12 class Data implements Serializable {
13     private static final long serialVersionUID = 3502676600783498362L;
14     private String name;
15     public Data(String name){this.name=name;}
16     public String toString(){return "d:"+name;}
17 }
18 
19 //Serializable 为序列化标记接口,不包括任何方法
20 class User implements Serializable {
21     //序列化标识,用于标记类是否发生变化
22     private static final long serialVersionUID = -6950896768312602572L;
23     private transient String id;        //transient关键字可以阻止该字段被序列化
24     private String name;
25     private int age;
26     private Data data;        //包含另一个对象
27     public static String kind="human";        //static 字段也可序列化
28     public User(String id, String name, int age){
29         this.id=id;
30         this.name=name;
31         this.age=age;
32         this.data=http://www.mamicode.com/new Data(name);
33     }
34     @Override
35     public String toString(){
36         return "["+id+"-"+name+"-"+age+"-"+kind+"-"+data+"]";
37     }
38 }
39 
40 public class SerialUtil {
41     //序列化会暴露对象所有信息(包括private),所以要对敏感信息加密后再序列化
42     public static void main(String[] args) throws IOException, ClassNotFoundException {
43         serialize();        //序列化
44         deSerialize();        //反序列化
45     }
46 
47     public static void serialize() throws IOException {
48         User bean1 = new User("1", "lg", 123);
49         User bean2 = new User("2", "ss", 23);
50         //ObjectOutputStream为对象输出流,输出到users文件中,名称后缀随意
51         ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(new File("users")));
52         oo.writeObject(bean1);        //将对象序列化到输出流中
53         oo.writeObject(bean2);        //写入另一个
54         oo.close();
55     }
56 
57     //如果远程jvm中没有User.class,将抛出ClassNotFoundException
58     public static void deSerialize() throws IOException, ClassNotFoundException {
59         //使用ObjectInputStream对象输入流读取文件,反序列化对象
60         ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("users")));
61         User bean1 = (User) ois.readObject();        //通过二进制构造对象,并不是通过构造函数
62         User bean2 = (User) ois.readObject();        //读取下一个
63         ois.close();
64         System.out.println(bean1);
65         System.out.println(bean2);
66     }
67 
68 }

 ----------------------------

输出结果:

<style>p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }</style>

[null-lg-123-human-d:lg]

[null-ss-23-human-d:ss]

 

 

 

 

如果需要进一步定制序列化反序列化过程,可通过实现接口Externalizable,实现writeExternal和readExternal方法,下面是一个例子:

---------------------------------

 1 package demos;
 2 
 3 import java.io.Externalizable;
 4 import java.io.FileInputStream;
 5 import java.io.FileNotFoundException;
 6 import java.io.FileOutputStream;
 7 import java.io.IOException;
 8 import java.io.ObjectInput;
 9 import java.io.ObjectInputStream;
10 import java.io.ObjectOutput;
11 import java.io.ObjectOutputStream;
12 
13 public class SerializeBean implements Externalizable{
14     private int i;
15     private String s;
16     private String ss;
17     
18     //从运行结果可见反序列化需要调用该默认构造器,如果为private则会抛出InvalidClassException
19     public SerializeBean(){
20         System.out.println("SerializeBean default constractor.");
21     }
22     
23     public SerializeBean(int i, String s, String ss){
24         this.i=i;
25         this.s=s;
26         this.ss=ss;
27     }
28     
29     @Override
30     public String toString(){
31         return "["+i+"-"+s+"-"+ss+"]";
32     }
33     
34     //序列化过程中自动调用
35     @Override
36     public void writeExternal(ObjectOutput out) throws IOException {
37         System.out.println("writeExternal here");
38         out.writeObject(s);        //此处添加需要序列化的属性
39         out.writeInt(i);
40     }
41 
42     //反序列化过程中自动调用
43     @Override
44     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
45         System.out.println("readExternal here");
46         s=(String)in.readObject();        //此处添加自定义处理逻辑
47         i=in.readInt();
48     }
49     
50     public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
51         SerializeBean bean1 = new SerializeBean(99, "iamstring","ss");
52         SerializeBean bean2 = new SerializeBean(-44, "string too", "ss");
53         
54         //序列化到文件
55         ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("out"));
56         oos.writeObject(bean1);
57         oos.writeObject(bean2);
58         oos.close();
59         bean1=null;
60         bean2=null;
61         
62         //从文件反序列化
63         ObjectInputStream ois = new ObjectInputStream(new FileInputStream("out"));
64         bean1 = (SerializeBean)ois.readObject();
65         bean2 = (SerializeBean)ois.readObject();
66         System.out.println(bean1);
67         System.out.println(bean2);
68     }
69 
70 }

 

---------------------------------

输出:

<style>p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Monaco }</style>

writeExternal here

writeExternal here

SerializeBean default constractor.

readExternal here

SerializeBean default constractor.

readExternal here

[99-iamstring-null]

[-44-string too-null]

 

ss并未序列化,可见起值为null

序列化反序列化