2015-05-13 33 views
1
class A extends Serializable{ 
     public A(){} 
int x=0; 
     private final transient ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); 

    } 

問題: 1)爲什麼需要提供默認的構造函數的情況下,序列化? 2)爲什麼字段「鎖定」在反序列化之後沒有被初始化?反序列化的步驟數約反序列化

編輯:忘了在我原來的帖子中添加「瞬態」。現在添加它。

+0

'可串行化'是一個接口,因此它應該是'implements Serializable' –

+0

'2)爲什麼字段「鎖定」在反序列化之後沒有被初始化?因爲它是暫時的。 – EpicPandaForce

+0

@ EpicPandaForce,由於其瞬態特性,鎖不會被破壞。但爲什麼它沒有被一個新對象「初始化」?實際上,我想了解反序列化的步驟,因爲它沒有被初始化? – pjain

回答

1

1)爲什麼在序列化的情況下需要提供默認構造函數。

這不是要求。或者至少,如果使用ObjectInputStreamObjectOutputStream實現的序列化,則不是必需的。

2)爲什麼字段「lock」在反序列化後沒有被初始化?

它應該被初始化......如果您使用的是ObjectInputStreamObjectOutputStream。應該序列化lock對象,然後反序列化。

(如果你有其中lock顯然沒有被初始化的話,那麼請張貼的SSCCE顯示發生了什麼。)

我錯誤地斷言,ReentrantReadWriteLock是不可序列...這是。

UPDATE與版本transientA的反序列化實例的lock字段將爲nulllock聲明中的初始化表達式不會被執行。

欲瞭解更多信息,請閱讀Java Object Serialization Specification


如果您正在使用某種其他序列化機制,您需要說出它是什麼。

1
  1. 不需要
  2. 鎖被初始化,下面的代碼不會打印初始化鎖(只是寫的B對象中的字節數組,並從中讀回)

    public class B implements Serializable { 
        private int x = 0; 
        private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); 
    
        public static void main(String[] args) throws IOException, ClassNotFoundException { 
         ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
         try (ObjectOutput out = new ObjectOutputStream(bos)) { 
          out.writeObject(new B()); 
         } 
         catch (IOException e) { 
          e.printStackTrace(); 
          throw e; 
         } 
         byte[] bytes = bos.toByteArray(); 
    
         ByteArrayInputStream bis = new ByteArrayInputStream(bytes); 
         try (ObjectInput in = new ObjectInputStream(bis)) { 
          B b = (B) in.readObject(); 
          System.out.println(b.lock); 
         } 
         catch (IOException e) { 
          e.printStackTrace(); 
          throw e; 
         } 
         } 
        } 
    }