乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      什么是writeObject 和readObject?可定制的序列化過(guò)程

       燮羽 2010-11-27
      這篇文章很直接,簡(jiǎn)單易懂。嘗試著翻譯一下 ,原文是What are writeObject and readObject? Customizing the serialization process. 

      在Java中使用Serialization相當(dāng)簡(jiǎn)單。如果你有一些對(duì)象想要進(jìn)行序列化,你只需實(shí)現(xiàn)Serializable接口。然后,你可以使用ObjectOutputStream將該對(duì)象保存至文件或發(fā)送到其他主機(jī)。所有的non-transient和non-static字段都將被序列化,并且由反序列化重構(gòu)造出一模一樣的對(duì)象聯(lián)系圖(譬如許多引用都指向該對(duì)象)。但有時(shí)你可能想實(shí)現(xiàn)你自己的對(duì)象序列化和反序列化。那么你可以在某些特定情形下得到更多的控制。來(lái)看下面的簡(jiǎn)單例子。 
      Java代碼 
      1. class SessionDTO implements Serializable {  
      2.     private static final long serialVersionUID = 1L;  
      3.     private int data; // Stores session data  
      4.   
      5.     // Session activation time (creation, deserialization)  
      6.     private long activationTime;   
      7.   
      8.     public SessionDTO(int data) {  
      9.         this.data = data;  
      10.         this.activationTime = System.currentTimeMillis();  
      11.     }  
      12.   
      13.     public int getData() {  
      14.         return data;  
      15.     }  
      16.   
      17.     public long getActivationTime() {  
      18.         return activationTime;  
      19.     }  
      20. }  

      以下是序列化上述class到文件和其反序列化的主函數(shù)。 
      Java代碼 
      1. public class SerializeTester implements Serializable {  
      2.     public static void main(String... strings) throws Exception {  
      3.         File file = new File("out.ser");  
      4.   
      5.         ObjectOutputStream oos = new ObjectOutputStream(  
      6.             new FileOutputStream(file));  
      7.         SessionDTO dto = new SessionDTO(1);  
      8.         oos.writeObject(dto);  
      9.         oos.close();  
      10.   
      11.         ObjectInputStream ois = new ObjectInputStream(  
      12.             new FileInputStream(file));  
      13.         SessionDTO dto = (SessionDTO) ois.readObject();  
      14.   
      15.         System.out.println("data : " + dto.getData()  
      16.             + " activation time : " + dto.getActivationTime());  
      17.         ois.close();  
      18.     }  
      19. }  

      類SessionDTO展現(xiàn)的是要在兩個(gè)服務(wù)器之間傳輸?shù)膕ession。它包含了一些信息在字段data上,該字段需要被序列化。但是它還有另外一個(gè)字段activationTime,該字段應(yīng)該是session對(duì)象第一次出現(xiàn)在任意服務(wù)器上的時(shí)間。它不在我們想要傳輸?shù)男畔⒅小_@個(gè)字段應(yīng)該在反序列化之后在賦值。進(jìn)一步來(lái)說(shuō),沒(méi)必要把它放在stream中在服務(wù)器中傳遞,因?yàn)樗紦?jù)了不必要的空間。 

      解決這種情況可以使用writeObject和readObject。有可能你們有一些人沒(méi)有聽(tīng)說(shuō)過(guò)它們,那是因?yàn)樗鼈冊(cè)谠S多Java書(shū)籍中給忽略了,而且它們們也不是眾多流行Java考試的一部分。讓我們用這些方法來(lái)重寫(xiě)SessionDTO: 
      Java代碼 
      1. class SessionDTO implements Serializable {  
      2.     private static final long serialVersionUID = 1L;  
      3.     private transient int data; // Stores session data  
      4.   
      5.     //Session activation time (creation, deserialization)  
      6.     private transient long activationTime;   
      7.   
      8.     public SessionDTO(int data) {  
      9.         this.data = data;  
      10.         this.activationTime = System.currentTimeMillis();  
      11.     }  
      12.   
      13.     private void writeObject(ObjectOutputStream oos) throws IOException {  
      14.         oos.defaultWriteObject();  
      15.         oos.writeInt(data);  
      16.         System.out.println("session serialized");  
      17.     }  
      18.   
      19.     private void readObject(ObjectInputStream ois) throws IOException,  
      20.             ClassNotFoundException {  
      21.         ois.defaultReadObject();  
      22.         data = ois.readInt();  
      23.         activationTime = System.currentTimeMillis();  
      24.         System.out.println("session deserialized");  
      25.     }  
      26.   
      27.     public int getData() {  
      28.         return data;  
      29.     }  
      30.   
      31.     public long getActivationTime() {  
      32.         return activationTime;  
      33.     }  
      34. }  

      方法writeObject處理對(duì)象的序列化。如果聲明該方法,它將會(huì)被ObjectOutputStream調(diào)用而不是默認(rèn)的序列化進(jìn)程。如果你是第一次看見(jiàn)它,你會(huì)很驚奇盡管它們被外部類調(diào)用但事實(shí)上這是兩個(gè)private的方法。并且它們既不存在于java.lang.Object,也沒(méi)有在Serializable中聲明。那么ObjectOutputStream如何使用它們的呢?這個(gè)嗎,ObjectOutputStream使用了反射來(lái)尋找是否聲明了這兩個(gè)方法。因?yàn)镺bjectOutputStream使用getPrivateMethod,所以這些方法不得不被聲明為priate以至于供ObjectOutputStream來(lái)使用。 

      在兩個(gè)方法的開(kāi)始處,你會(huì)發(fā)現(xiàn)調(diào)用了defaultWriteObject()和defaultReadObject()。它們做的是默認(rèn)的序列化進(jìn)程,就像寫(xiě)/讀所有的non-transient和 non-static字段(但他們不會(huì)去做serialVersionUID的檢查).通常說(shuō)來(lái),所有我們想要自己處理的字段都應(yīng)該聲明為transient。這樣的話,defaultWriteObject/defaultReadObject便可以專注于其余字段,而我們則可為這些特定的字段(譯者:指transient)定制序列化。使用那兩個(gè)默認(rèn)的方法并不是強(qiáng)制的,而是給予了處理復(fù)雜應(yīng)用時(shí)更多的靈活性。 

      你可以從這里這里讀到更多有關(guān)于序列化的知識(shí)。 

      自己再補(bǔ)充一些: 

      1.Write的順序和read的順序需要對(duì)應(yīng),譬如有多個(gè)字段都用wirteInt一一寫(xiě)入流中,那么readInt需要按照順序?qū)⑵滟x值; 

      2.Externalizable,該接口是繼承于Serializable ,所以實(shí)現(xiàn)序列化有兩種方式。區(qū)別在于Externalizable多聲明了兩個(gè)方法readExternal和writeExternal,子類必須實(shí)現(xiàn)二者。Serializable是內(nèi)建支持的也就是直接implement即可,但Externalizable的實(shí)現(xiàn)類必須提供readExternal和writeExternal實(shí)現(xiàn)。對(duì)于Serializable來(lái)說(shuō),Java自己建立對(duì)象圖和字段進(jìn)行對(duì)象序列化,可能會(huì)占用更多空間。而Externalizable則完全需要程序員自己控制如何寫(xiě)/讀,麻煩但可以有效控制序列化的存儲(chǔ)的內(nèi)容。 

      3.正如Effectvie Java中提到的,序列化就如同另外一個(gè)構(gòu)造函數(shù),只不過(guò)是有由stream進(jìn)行創(chuàng)建的。如果字段有一些條件限制的,特別是非可變的類定義了可變的字段會(huì)反序列化可能會(huì)有問(wèn)題??梢栽趓eadObject方法中添加條件限制,也可以在readResolve中做。參考56條“保護(hù)性的編寫(xiě)readObject”和“提供一個(gè)readResolve方法”。 

      4.當(dāng)有非常復(fù)雜的對(duì)象需要提供deep clone時(shí),可以考慮將其聲明為可序列化,不過(guò)缺點(diǎn)也顯而易見(jiàn),性能開(kāi)銷。 

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多