2014-11-16 74 views
2

在序列化過程中靜態變量的值如何保持(如果全部持續存在)。我已經閱讀過堆棧中類似的問題,它說靜態變量本質上是暫態的,即它們的狀態或當前值沒有被序列化。java靜態變量序列化

我只是做了一個非常簡單的例子,我將一個類序列化並將其保存到一個文件中,然後再次從該文件重建該類。令人驚訝的是,我發現在發生序列化時靜態變量的值是保存。

這是怎麼發生的。這是因爲類模板及其實例信息在序列化期間被保存。這裏是代碼片段 -

public class ChildClass implements Serializable, Cloneable{ 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 5041762167843978459L; 

    private static int staticState; 
    int state = 0; 

    public ChildClass(int state){ 
     this.state = state; 
     staticState = 10001; 
    } 

    public String toString() { 
     return "state" + state + " " + "static state " + staticState; 
    } 

    public static void setStaticState(int state) { 
     staticState = state; 
    } 

,這裏是我的主類

public class TestRunner { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     new TestRunner().run(); 
    } 

    public TestRunner() { 

    } 

    public void run() { 
     ChildClass c = new ChildClass(101); 
     ChildClass.setStaticState(999999); 
     FileOutputStream fo = null; 
     ObjectOutputStream os = null; 

     File file = new File("F:\\test"); 
     try { 
      fo = new FileOutputStream(file); 
      os = new ObjectOutputStream(fo); 
      os.writeObject(c); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } finally { 

      try { 
       if(null != os)os.close(); 
       if(null != fo) fo.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

     } 


     FileInputStream fi = null; 
     ObjectInputStream ois = null; 
     ChildClass streamed; 

     try { 
      fi = new FileInputStream(file); 
      ois = new ObjectInputStream(fi); 
      Object o = ois.readObject(); 
      if(o instanceof ChildClass){ 
       streamed = (ChildClass)o; 
       //ChildClass cloned = streamed.clone(); 
       System.out.println(streamed.toString()); 
      } 
     } catch (IOException | ClassNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } finally { 
      try { 
       if(null != ois)ois.close(); 
       if(null != fi) fi.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

     } 
    } 

注:有沒有錯的代碼。我只是想知道'ChildClass'類中的靜態變量'staticState'的值是如何保存的。如果我通過網絡傳輸這個序列化數據,狀態會被保存嗎?

+1

[這個問題]的可能的複製(http://stackoverflow.com/questions/3147811/serialize-static-attributes-in-java)。我沒有「重複」這個問題,因爲我還不完全確定這是否合適。 –

+0

儘管我的問題是關於靜態變量的序列化,但我的問題是關於一個行爲,我注意到,實際上不是按照標準文檔。 – Dibzmania

回答

2

靜態字段值沒有被序列化。輸出打印靜態字段的新值僅僅是因爲您將其修改爲999999,但在去serizalizing之前,您絕不會將其值重置爲舊字段。由於該字段是靜態的,所以新值反映在的任何實例ChildClass中。

要正確地斷言該字段是不會被序列化,反序列化對象之前將值重置爲10001,而且你會發現,它的價值是不是999999

... 
ChildClass.setStaticState(10001); 

FileInputStream fi = null; 
ObjectInputStream ois = null; 
ChildClass streamed; 

... 
// when de-serializing, the below will print "state101 static state 10001" 
System.out.println(streamed.toString()); 
+0

這就是我的問題所在。是否反映了靜態變量的值變化,因爲我正在同一個程序中進行序列化和反序列化,即該類已在虛擬機中加載。如果序列化數據通過網絡發送,它將重置爲在構造函數中設置的值? – Dibzmania

+0

@Dibzmania是的,它會重置爲舊的。事實上,這裏的新價值是因爲該類已經加載到虛擬機中。 – manouti

+0

我會和你的確認一起去:-) – Dibzmania