2016-04-26 63 views
6

這裏是一個非常基本的測試程序:反序列化的對象是否保留靜態值?

public class Body implements Serializable { 
    static int bod = 5; 
    int dis = -1; 
    public void show(){ 
     System.out.println("Result: " + bod + " & " + dis); 
    } 
} 

public class Testing { 
    public static void main(String[] args) { 
     Body theBody = new Body(); 
     theBody.show(); 
     try { 
      ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("test.dat")); 
      out.writeObject(theBody); 
      out.close(); 
      ObjectInputStream in = new ObjectInputStream(new FileInputStream("test.dat")); 
      Body bodyDouble = (Body)in.readObject(); 
      in.close(); 
      bodyDouble.show(); 
     } catch(IOException e) { 
     } catch(ClassNotFoundException e) { 
     } 

    } 
} 

但我不明白爲什麼它的輸出是:

Result: 5 & -1 
Result: 5 & -1 

由於靜態成員沒有序列號,因此得到默認值,我期待另一個輸出:

Result: 5 & -1 
Result: 0 & -1 

反序列化的對象是如何獲得正確的靜態字段值的?

我做了這個測試應用程序,因爲我需要序列化幾個對象與一些靜態字段,以便使深拷貝(當然,我需要確保副本具有相同的靜態字段的值因爲它們被用作數組索引)。

現在我對反序列化後會發生什麼感到絕望。一方面,靜態成員不會被序列化,但另一方面,正如示例所證明的,靜態成員以某種方式保存了它們的值。我懷疑這與將readObject()轉換成Body對象有關,但我不確定。

+0

http://stackoverflow.com/questions/1008023/how-to-serialize-static-data-members-of-a-java-class – rkosegi

回答

6

反序列化的對象是如何獲得正確的靜態字段值的?

由於靜態字段值沒有序列化和反序列化之間改變:

您的同一應用程序內運行測試。因此,靜態類成員保留其價值。類iteself不會重新加載或重新初始化 - 它仍然是一樣的。

你應該在兩個獨立的應用程序分開測試:

  • 讓一個應用連載對象
  • 讓一個應用反序列化對象

然後運行這兩個應用程序一個接一個地。然後您會看到第二個應用程序中沒有恢復靜態成員。

或者,在上面的代碼中,您還可以在反序列化之前將靜態字段設置爲不同的值 - 然後您會看到該變量在反序列化之後仍然具有此值。

在附註上,千萬不要... catch(IOException e) {} ... - 至少用e.printStackTrace()打印堆棧跟蹤。

+0

謝謝。所以我知道它是正確的,因爲我需要在運行時臨時完全相同的對象深層副本(不涉及單獨的應用程序),我不需要擔心靜態字段 - 所有反序列化的副本都會擁有它們?即丟失靜態值基本上是不同應用程序之間對象交換的問題? – Vic

+0

是的。因爲序列化是關於對象(類實例),而不是類。這可能對您的特定用例有用:http://stackoverflow.com/questions/64036/how-do-you-make-a-deep-copy-of-an-object-in-java –