java序列化的实现

一. 自动序列化

  1. java中要序列化对象要时,只要实现Serilizable接口即可,默认对象的所有属性都会被序列化,但是静态变量(static)不能被序列化。

实例代码如下:

 1 public class Student implements Serializable {
 2 
 3     private static final long serialVersionUID = -2378603120577464262L;
 4 
 5     public Student(int id, String name, LocalDate birth) {
 6         this.id = id;
 7         this.name = name;
 8         this.birth = birth;
 9     }
10 
11     private int id;
12     private String name;
13     private LocalDate birth;
14 
15     public int getId() {
16         return id;
17     }
18 
19     public void setId(int id) {
20         this.id = id;
21     }
22 
23     public String getName() {
24         return name;
25     }
26 
27     public void setName(String name) {
28         this.name = name;
29     }
30 
31     public LocalDate getBirth() {
32         return birth;
33     }
34 
35     public void setBirth(LocalDate birth) {
36         this.birth = birth;
37     }
38 
39     @Override
40     public String toString() {
41         return "id=" + this.id + ";name=" + this.name + ";birth=" + this.birth;
42     }
43 }

序列化代码实现如下:

 1 public class TestClass {
 2 
 3     public static void main(String[] args) throws IOException {
 4         try {
 5             serialize();
 6         } catch (Exception e) {
 7             System.err.println(e);
 8         }
 9 
10         try {
11             deserialize();
12         } catch (Exception e) {
13             System.err.println(e);
14         }
15     }
16 
17     private final static String FILENAME = "D:\\workfolder\\abc.txt";
18 
19     public static void serialize() throws IOException {
21         Student student = new Student(10, "张三", LocalDate.of(2005, 10, 10));
22         System.out.println(student);
23         ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(FILENAME));
24         os.writeObject(student);
25         os.flush();
26         os.close();
27     }
28 
29     public static void deserialize() throws IOException, ClassNotFoundException {
30         ObjectInputStream stream = new ObjectInputStream(new FileInputStream(FILENAME));
31         Student student = (Student) stream.readObject();
32         stream.close();
33         System.out.println(student);
35     }
36 
37 }

结果显示:

id=10;name=张三;birth=2005-10-10
id=10;name=张三;birth=2005-10-10

 

有时候对象的某些属性不需要进行序列化,比方密码等敏感数据,可以在这些变量上加上 transient 关键字来修饰,用transient来修饰的属性则不会被序列化。

比如,将Student的birth属性改为如下:

private transient LocalDate birth;

重新执行序列化和反序列化,则如下结果:

id=10;name=张三;birth=2005-10-10
id=10;name=张三;birth=null

 

2.transient关键字只能修饰变量,而不能修饰方法和类。变量如果是用户自定义类变量,则该类需要实现Serializable接口。

二. 自定以序列化

 1: JDK中提供了另一个序列化接口--Externalizable,使用该接口之后,之前基于Serializable接口的序列化机制就将失效。Externalizable继承于Serializable,当使用该接口时,序列化的细节需要由程序员去完成。

实例代码如下:

 1 public class TestClass {
 2 
 3     public static void main(String[] args) {
 4         try {
 5             serialize();
 6         } catch (Exception e) {
 7             System.err.println(e);
 8         }
 9 
10         try {
11             deserialize();
12         } catch (Exception e) {
13             System.err.println(e);
14         }
15     }
16 
17     private final static String FILENAME = "D:\\workfolder\\abc.txt";
18 
19     public static void serialize() throws IOException {
20          Address address =  new Address("广东省", "广州市", "天河区");
21         ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(FILENAME));
22         os.writeObject(address);
23         os.flush();
24         os.close();
25     }
26 
27     public static void deserialize() throws IOException, ClassNotFoundException {
28         ObjectInputStream stream = new ObjectInputStream(new FileInputStream(FILENAME));
29         Address address = (Address) stream.readObject();
30         stream.close();
31         System.out.println(address);
32      }
33 }
 1 public class Address implements Externalizable {
 2  
 3     private String sheng;
 4     private String shi;
 5     private String qu;
 6  
 7     public Address() {
        System.out.println("init...");
8 } 9 10 public Address(String sheng, String shi, String qu) { 11 super(); 12 this.sheng = sheng; 13 this.shi = shi; 14 this.qu = qu; 15 } 16 17 public String getSheng() { 18 return sheng; 19 } 20 21 public void setSheng(String sheng) { 22 this.sheng = sheng; 23 } 24 25 public String getShi() { 26 return shi; 27 } 28 29 public void setShi(String shi) { 30 this.shi = shi; 31 } 32 33 public String getQu() { 34 return qu; 35 } 36 37 public void setQu(String qu) { 38 this.qu = qu; 39 } 40 41 @Override 42 public String toString() { 43 return "sheng=" + this.sheng + ";shi=" + this.shi + ";qu=" + this.qu; 44 } 45 46 @Override 47 public void writeExternal(ObjectOutput out) throws IOException { 48 49 out.writeUTF(sheng); 50 out.writeUTF(shi); 51 out.writeUTF(qu); 52 } 53 54 @Override 55 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { 56 sheng = in.readUTF(); 57 shi = in.readUTF(); 58 qu = in.readUTF(); 59 } 60 }

输出结果如下:
init...
sheng=广东省;shi=广州市;qu=天河区

使用Externalizable进行序列化,对象必须有一个无参的构造函数,且访问权限为public,当读取对象时,会调用被序列化类的无参构造器去创建一个新的对象,然后再将被保存对象的字段的值分别填充到新对象中。

2: 实现Serializable , 添加下列两个方法,

private void writeObject(java.io.ObjectOutputStream s) throws IOException {
 ...
}

private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
  ...
}

具体实现略

posted @ 2017-10-28 00:08  南极山  阅读(500)  评论(0)    收藏  举报