序列化與反序列化
Prerequisites:
裝飾串流ObjectInputStream與ObjectOutputStream
ObjectOutputStream 把物件寫入。
ObjectInputStream 讀取物件。
寫入基本類型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public static void main(String[] args) {
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
// 讀取與寫入的位置是在記憶體緩衝區
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
// 寫入基本資料型態
// 寫入整數
oos.writeInt(100);
// 寫入布林
oos.writeBoolean(true);
// 寫入字元
oos.writeChar('A');
// 寫入浮點數
oos.writeDouble(5.99);
// 寫入字串,是使用writeUTF()
oos.writeUTF("測試");
// 讀取物件
ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
// 要按照寫入順序讀取
System.out.println(ois.readInt());
System.out.println(ois.readBoolean());
System.out.println(ois.readChar());
System.out.println(ois.readDouble());
System.out.println(ois.readUTF());
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
// 只需要關閉裝飾串流,詳見裝飾串流文章
if (oos != null)
oos.close();
if (ois != null)
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
100
true
A
5.99
測試
將物件寫到串流
物件都要implements Serializable
Student
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class Student implements Serializable {
private String name;
private int age;
// 成員變數family是類別
private Family family;
public Student() {
family = new Family();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getMother() {
return family.getMother();
}
public void setMother(String mother) {
family.setMother(mother);
}
public String getFather() {
return family.getFather();
}
public void setFather(String father) {
family.setFather(father);
}
}
成員變數類別也要implements Serializable
Family是Student的成員變數類別,也要implements Serializable
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Family implements Serializable {
private String mother;
private String father;
public String getMother() {
return mother;
}
public void setMother(String mother) {
this.mother = mother;
}
public String getFather() {
return father;
}
public void setFather(String father) {
this.father = father;
}
}
程式碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public static void main(String[] args) {
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
// 寫入基本資料型態
oos.writeInt(100);
oos.writeBoolean(true);
oos.writeChar('A');
oos.writeDouble(5.99);
// 寫入字串
oos.writeUTF("測試");
// 寫入物件
Student student = new Student();
student.setName("小美");
student.setAge(10);
student.setMother("小美媽");
student.setFather("小美爸");
oos.writeObject(student);
// 讀取物件
ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
// 要按照寫入順序讀取
System.out.println(ois.readInt());
System.out.println(ois.readBoolean());
System.out.println(ois.readChar());
System.out.println(ois.readDouble());
System.out.println(ois.readUTF());
// readObject()是Object物件
// 向下轉型成Student才能使用Student的方法
Student copy = (Student) ois.readObject();
System.out.println(copy.getName());
System.out.println(copy.getAge());
System.out.println(copy.getFather());
System.out.println(copy.getMother());
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
// 只需要關閉裝飾串流,詳見裝飾串流文章
if (oos != null)
oos.close();
if (ois != null)
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
100
true
A
5.99
測試
小美
10
小美爸
小美媽
Deep Clone程式碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 建立byte陣列寫出串流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 為byte陣列輸出串流 加上物件的功能
// 原文: adds functionality to output stream
ObjectOutputStream oos = new ObjectOutputStream(baos);
// 把物件寫入byte陣列
// 使用ObjectOutputStream.writeObject()
oos.writeObject(object);
// 建立byte陣列讀取串流, 資料的來源是byte陣列
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
// 為byte陣列輸入串流 加上物件的功能
// 原文: adds functionality to input stream
ObjectInputStream ois = new ObjectInputStream(bais);
// 把物件讀取出來
// 使用ObjectInputStream.readObject()
return (T) ois.readObject();