什麼情況下需要序列化?
A)當你想把的內存中的對象寫入到硬盤的時候;
比如說你的內存不夠用了,那計算機就要將內存裏面的一部分對象暫時的保存到硬盤中,等到要用的時候再讀入到內存中,硬盤的那部分存儲空間就是所謂的虛擬內存。在比如過你要將某個特定的對象保存到文件中,我隔幾天在把它拿出來用,那麼這時候就要實現Serializable接口;
B)當你想用套接字在網絡上傳送對象的時候;(注意套接字就如手機,如要socket與serversocket)
在進行java的Socket編程的時候,你有時候可能要傳輸某一類的對象,那麼也就要實現Serializable接口;最常見的你傳輸一個字符串,它是JDK裏面的類,也實現了Serializable接口,所以可以在網絡上傳輸。
C)當你想通過RMI傳輸對象的時候;
如果要通過遠程的方法調用(RMI)去調用一個遠程對象的方法,如在計算機A中調用另一臺計算機B的對象的方法,那麼你需要通過JNDI服務獲取計算機B目標對象的引用,將對象從B傳送到A,就需要實現序列化接口。
爲什麼需要序列化和反序列化?
當兩個進程在進行遠程通信時,彼此可以發送各種類型的數據。無論是何種類型的數據,都會以二進制序列的形式在網絡上傳送。發送方需要把這個Java對象轉換爲字節序列,才能在網絡上傳送;接收方則需要把字節序列再恢復爲Java對象。
把Java對象轉換爲字節序列的過程稱爲對象的序列化。把字節序列恢復爲Java對象的過程稱爲對象的反序列化。
對象的序列化主要有兩種用途:
1) 持久化:把對象的字節序列永久地保存到硬盤上,通常存放在一個文件中;比如:休眠的實現。以後服務器session管理,hibernate將對象持久化實現。
2) 網絡通信:在網絡上傳送對象的字節序列。比如:服務器之間的數據通信,對象傳遞。
序列化涉及的類和接口:
java.io.ObjectOutputStream代表對象輸出流,它的writeObject(Object obj)方法可對參數指定的obj對象進行序列化,把得到的字節序列寫到一個目標輸出流中。
java.io.ObjectInputStream代表對象輸入流,它的readObject()方法從一個源輸入流中讀取字節序列,再把它們反序列化爲一個對象,並將其返回。
只有實現了Serializable接口的類的對象才能被序列化。
序列化/反序列化的步驟和簡單測試:
1. 將類Person的實例進行序列化和反序列化:
a) Person類實現Serializable接口:
public class Person implements Serializable{
int age;
boolean bool;
String name;
public Person(int age,boolean bool,String name){
super();
this.age=age;
this.bool=bool;
this.name=name;
}
b) 通過ObjectOutputStream將Person對象的數據寫入到文件中,即序列化。
Person person=new Person(20,true,"aa");
FileOutputStream fos=null;
ObjectOutputStream oos=null;
try {
fos=new FileOutputStream("d:/m.txt");
oos=new ObjectOutputStream(fos);
oos.writeObject(person);
oos.writeObject(new Date());
oos.flush();
oos.close();
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
c)通過ObjectInputStream將文件中二進制數據反序列化成Person對象:
FileInputStream f=null;
ObjectInputStream o=null;
try {
f=new FileInputStream("d:/m.txt");
o=new ObjectInputStream(f);
Person p=(Person)o.readObject();
Date d=(Date)o.readObject();
System.out.println(p.age+p.name+p.bool+d);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}