日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
為什么使用Serializable(序列化)

經(jīng)常看到有些類調(diào)用了Serializable接口,而有些類又沒有調(diào)用Serializable接口。那么什么情況下要調(diào)用Serializable接口。

首先來了解一下Serializable。(類通過實現(xiàn) java.io.Serializable 接口以啟用其序列化功能。未實現(xiàn)此接口的類將無法使其任何狀態(tài)序列化或反序列化。序列化接口Serializable沒有方法或字段,僅用于標(biāo)識可序列化的語義)

實現(xiàn)了Serializable接口的對象,可將它們轉(zhuǎn)換成一系列字節(jié),并可在以后完全恢復(fù)回原來的樣子。這一過程亦可通過網(wǎng)絡(luò)進(jìn)行。這意味著序列化機(jī)制能自動補(bǔ)償操作系統(tǒng)間的差異。換句話說,可以先在Windows機(jī)器上創(chuàng)建一個對象,對其序列化,然后通過網(wǎng)絡(luò)發(fā)給一臺Unix機(jī)器,然后在那里準(zhǔn)確無誤地重新“裝配”。不必關(guān)心數(shù)據(jù)在不同機(jī)器上如何表示,也不必關(guān)心字節(jié)的順序或者其他任何細(xì)節(jié)。

serialization主要用來支持2種主要的特性:

1、RMI(Remote method invocation)。

RMI允許象在本機(jī)上一樣操作遠(yuǎn)程機(jī)器上的對象。當(dāng)發(fā)送消息給遠(yuǎn)程對象和調(diào)用遠(yuǎn)程方法時,就需要用到serializaiton機(jī)制來發(fā)送參數(shù)和接收返回值。

2、保存信息。

在某個時候把狀態(tài)信息保存起來,以便以后某個時候能恢復(fù)這些狀態(tài)信息。

Hibernaet和EJB中的實體Bean就用到了上面兩個特性。

另外:保存的時候不僅能保存對象的副本,而且還會把對象里面所引用的對象也保存起來,以此類推。就像在編譯某個類一樣,會涉及到所用到的所有類。但是所引用的對象也必須是可序列化的,不然會拋NotSerializableException異常。

下面來寫個例子:(A和B類都是可序列化的,WriteObj:將A序列化,ReadObj:將A反序列化)

class A:

 
 
 
  1. package woxingwosu;
  2. import java.io.Serializable;
  3. public class A implements Serializable{
  4. private String name="my name is a";
  5. private B b=null;
  6. A(){
  7. b=new B();
  8. }
  9. public B getB() {
  10. return b;
  11. }
  12. public void setB(B b) {
  13. this.b = b;
  14. }
  15. public String getName() {
  16. return name;
  17. }
  18. public void setName(String name) {
  19. this.name = name;
  20. }
  21. public String show(){
  22. return "a.toString "
  23. +"\na="+this.toString()+" b="+this.b.toString();
  24. }
  25. }

class B:

 
 
 
  1. package woxingwosu;
  2. import java.io.Serializable;
  3. public class B implements Serializable{
  4. private String name="my name is B";
  5. B(){}
  6. public String getName() {
  7. return name;
  8. }
  9. public void setName(String name) {
  10. this.name = name;
  11. }
  12. }

class WriteSeri:

 
 
 
  1. package woxingwosu;
  2. import java.io.FileOutputStream;
  3. import java.io.ObjectOutputStream;
  4. /**
  5. * 寫Object(系列化)
  6. * @author 我行我素
  7. */
  8. public class WriteSeri {
  9. public static void main(String[] args) {
  10. ObjectOutputStream outObj=null;
  11. try{
  12. FileOutputStream outStr=new FileOutputStream("obj.txt");
  13. outObj=new ObjectOutputStream(outStr);
  14. A a=new A();
  15. outObj.writeObject(a);
  16. System.out.println("write obj :"+a.show());
  17. outObj.flush();
  18. }catch(Exception e){
  19. e.printStackTrace();
  20. }finally{
  21. try{
  22. if(outObj!=null)
  23. outObj.close();
  24. }catch(Exception e){
  25. e.printStackTrace();
  26. }
  27. }
  28. }}

class ReadSeri:

 
 
 
  1. package woxingwosu;
  2. import java.io.FileInputStream;
  3. import java.io.ObjectInputStream;
  4. /**
  5. * 讀Object(反系列化)
  6. * @author 我行我素
  7. */
  8. public class ReadSeri {
  9. public static void main(String[] args) {
  10. ObjectInputStream inObj=null;
  11. try{
  12. FileInputStream inStr=new FileInputStream("obj.txt");
  13. inObj=new ObjectInputStream(inStr);
  14. A a=(A)inObj.readObject();
  15. System.out.println("read Object :"+a.show());
  16. }catch(Exception e){
  17. e.printStackTrace();
  18. }finally{
  19. try{
  20. if(inObj!=null)
  21. inObj.close();
  22. }catch(Exception e){
  23. e.printStackTrace();
  24. }
  25. }
  26. }
  27. }

首先,我們運行WriteObj,實現(xiàn)序列化,得到輸出結(jié)果

 
 
 
  1. write obj :a.toString 
  2. a=woxingwosu.A@a90653 b=woxingwosu.B@de6ced 

然后我們再運行ReadObj,實現(xiàn)反序列化,得到輸出結(jié)果

 
 
 
  1. read Object :a.toString 
  2. a=woxingwosu.A@a90653 b=woxingwosu.B@de6ced

遺漏了一個問題,就是標(biāo)識版本的serialVersionUID。

官方文檔:如果可序列化類未顯式聲明 serialVersionUID,則序列化運行時將基于該類的各個方面計算該類的默認(rèn) serialVersionUID 值,如“Java(TM) 對象序列化規(guī)范”中所述。不過,強(qiáng)烈建議 所有可序列化類都顯式聲明 serialVersionUID 值,原因計算默認(rèn)的 serialVersionUID 對類的詳細(xì)信息具有較高的敏感性,根據(jù)編譯器實現(xiàn)的不同可能千差萬別,這樣在反序列化過程中可能會導(dǎo)致意外的 InvalidClassException。因此,為保證 serialVersionUID 值跨不同 java 編譯器實現(xiàn)的一致性,序列化類必須聲明一個明確的 serialVersionUID 值。還強(qiáng)烈建議使用 private 修改器顯示聲明 serialVersionUID(如果可能),原因是這種聲明僅應(yīng)用于立即聲明類 -- serialVersionUID 字段作為繼承成員沒有用處。

剛才寫的例子中就沒有用到serialVersionUID,這時JVM會根據(jù)類名、接口名、成員方法及屬性等來生成一個64位的哈希字段作為serialVersionUID。但是如果序列化和反序列化的JVM版本不一樣的話,還是顯示寫上serialVersionUID安全。

以上是個人看法,如有錯誤之處,還望指出。

原文地址:http://www.blogjava.net/woxingwosu/archive/2007/07/12/129511.html


本文題目:為什么使用Serializable(序列化)
網(wǎng)頁鏈接:http://www.dlmjj.cn/article/djoidgj.html