2014-11-16 36 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