當(dāng)兩個(gè)進(jìn)程在進(jìn)行遠(yuǎn)程通信時(shí),無論是何種類型的數(shù)據(jù),都會(huì)以二進(jìn)制序列的形式在網(wǎng)絡(luò)上傳送。發(fā)送方需要把這個(gè)Java對象轉(zhuǎn)換為字節(jié)序列,才能在網(wǎng)絡(luò)上傳送,稱為對象的序列化;接收方則需要把字節(jié)序列再恢復(fù)為Java對象,稱為對象的反序列化。 只有實(shí)現(xiàn)了Serializable和Externalizable接口的類的對象才能被序列化,而Externalizable接口又繼承自Serializable接口。下面是序列化和外部化接口代碼:

SerializableMyTest
1
package serializableTest;
2
3
import java.io.FileInputStream;
4
import java.io.FileOutputStream;
5
import java.io.ObjectInputStream;
6
import java.io.ObjectOutputStream;
7
import java.io.Serializable;
8
import java.util.Date;
9
10
public class SerializableMyTest
{
11
12
public static void main(String[] args) throws Exception
{
13
// TODO Auto-generated method stub
14
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
15
"shit.obj"));
16
Customer customer = new Customer("Gefforey", 23);
17
out.writeObject("Hello,gefforey");
18
out.writeObject(new Date());
19
out.writeObject(customer);
20
out.writeInt(520);
21
out.close();
22
23
System.out.println();
24
ObjectInputStream in = new ObjectInputStream(new FileInputStream(
25
"shit.obj"));
26
System.out.println("obj1=" + (String) in.readObject());
27
System.out.println("obj2=" + (Date) in.readObject());
28
System.out.println("obj3:" + (Customer) in.readObject());
29
System.out.println("obj4=" + in.readInt());
30
in.close();
31
}
32
}
33
34
class Customer implements Serializable
{
35
public String name;
36
37
public int age;
38
39
public Customer(String name, int age)
{
40
this.name = name;
41
this.age = age;
42
}
43
44
public String toString()
{
45
return "name=" + name + ",age=" + age + ".";
46
}
47
}
48
obj1=Hello,gefforey
obj2=Sat Jun 20 17:32:20 CST 2009
obj3:name=Gefforey,age=23.
obj4=520

AppTest
1
package serializableTest;
2
3
import java.io.Externalizable;
4
import java.io.FileInputStream;
5
import java.io.FileOutputStream;
6
import java.io.IOException;
7
import java.io.ObjectInput;
8
import java.io.ObjectInputStream;
9
import java.io.ObjectOutput;
10
import java.io.ObjectOutputStream;
11
import java.io.Serializable;
12
13
14
//必須得實(shí)現(xiàn)Serializable接口
15
//writing aborted; java.io.NotSerializableException: serializableTest.Customer2
16
class Customer2 implements Serializable
{
17
public String name;
18
19
public int age;
20
21
@Override
22
public int hashCode()
{
23
final int PRIME = 31;
24
int result = 1;
25
result = PRIME * result + age;
26
result = PRIME * result + ((name == null) ? 0 : name.hashCode());
27
return result;
28
}
29
30
@Override
31
public boolean equals(Object obj)
{
32
if (this == obj)
33
return true;
34
if (obj == null)
35
return false;
36
if (getClass() != obj.getClass())
37
return false;
38
final Customer2 other = (Customer2) obj;
39
if (age != other.age)
40
return false;
41
if (name == null)
{
42
if (other.name != null)
43
return false;
44
} else if (!name.equals(other.name))
45
return false;
46
return true;
47
}
48
49
public Customer2(String name, int age)
{
50
this.name = name;
51
this.age = age;
52
}
53
54
public String toString()
{
55
return "name=" + name + ",age=" + age + ".";
56
}
57
}
58
59
60
/**//*
61
* 相當(dāng)于要序列化得類
62
*/
63
class Customer3 implements Externalizable
{ // Test類必須實(shí)現(xiàn)Externalizable接口
64
private String letterstates = "gefforey";
65
66
private int num = 0;
67
68
//要序列化得類中還可以加需要序列化的類,Customer2也要實(shí)現(xiàn)Serilizable接口
69
private Customer2 cus =new Customer2("ffffffffff",24);
70
71
public Customer3()
{
72
}
73
74
public void writeExternal(ObjectOutput out) throws IOException
{
75
out.writeObject(letterstates);
76
out.write(88); // 在序列化的數(shù)據(jù)最后加個(gè)88
77
out.writeObject(cus);
78
System.out.println("in writeExternal---"+cus.hashCode());
79
}
80
81
public void readExternal(ObjectInput in) throws IOException,
82
ClassNotFoundException
{
83
letterstates = (String) in.readObject();
84
num = in.read(); // 把數(shù)字88加進(jìn)來
85
Customer2 cusTemp = (Customer2) in.readObject();
86
System.out.println("cus==cusTemp---"+(cus==cusTemp));
87
System.out.println("in readExternal---"+cus.hashCode());
88
89
}
90
91
public void printOut()
{ // 測試
92
System.out.println(letterstates +"--"+num);
93
}
94
}
95
96
public class AppTest
{
97
private void saveGame()
{
98
Customer3 m = new Customer3();
99
if (m != null)
{
100
try
{
101
FileOutputStream ostream = new FileOutputStream("t.txt");
102
ObjectOutputStream p = new ObjectOutputStream(ostream);
103
104
p.writeObject(m); // writeExternal()自動(dòng)執(zhí)行
105
106
p.flush();
107
ostream.close();
108
} catch (IOException ioe)
{
109
System.out.println("Error saving file:");
110
System.out.println(ioe.getMessage());
111
}
112
}
113
}
114
115
private void loadGame()
{
116
try
{
117
FileInputStream instream = new FileInputStream("t.txt");
118
ObjectInputStream p = new ObjectInputStream(instream);
119
Customer3 m = (Customer3) p.readObject();// readExternal()自動(dòng)執(zhí)行
120
m.printOut();
121
instream.close();
122
} catch (Exception e)
{
123
System.out.println("Error loading file:");
124
System.out.println(e.getMessage());
125
}
126
}
127
128
public static void main(String[] args)
{
129
new AppTest().saveGame();
130
new AppTest().loadGame();
131
}
132
}
133
in writeExternal----1524332777
cus==cusTemp---false
in readExternal----1524332777
gefforey--88
序列化會(huì)自動(dòng)存儲(chǔ)必要的信息,用以反序列化被存儲(chǔ)的實(shí)例,而外部化則只保存被存儲(chǔ)的類的標(biāo)識(shí)。當(dāng)你通過java.io.Serializable接口序列化一個(gè)對象時(shí),有關(guān)類的信息,比如它的屬性和這些屬性的類型,都與實(shí)例數(shù)據(jù)一起被存儲(chǔ)起來。在選擇走Externalizable這條路時(shí),Java 只存儲(chǔ)有關(guān)每個(gè)被存儲(chǔ)類型的非常少的信息。
每個(gè)接口的優(yōu)點(diǎn)和缺點(diǎn)
Serializable接口
· 優(yōu)點(diǎn):內(nèi)建支持
· 優(yōu)點(diǎn):易于實(shí)現(xiàn)
· 缺點(diǎn):占用空間過大
· 缺點(diǎn):由于額外的開銷導(dǎo)致速度變比較慢
Externalizable接口
· 優(yōu)點(diǎn):開銷較少(程序員決定存儲(chǔ)什么)
· 優(yōu)點(diǎn):可能的速度提升
· 缺點(diǎn):虛擬機(jī)不提供任何幫助,也就是說所有的工作都落到了開發(fā)人員的肩上。
在兩者之間如何選擇要根據(jù)應(yīng)用程序的需求來定。Serializable通常是最簡單的解決方案,但是它可能會(huì)導(dǎo)致出現(xiàn)不可接受的性能問題或空間問題;在出現(xiàn)這些問題的情況下,Externalizable可能是一條可行之路。
posted on 2009-06-20 17:43
Frank_Fang 閱讀(489)
評(píng)論(1) 編輯 收藏 所屬分類:
Java編程