为什么静态变量是序列化的?

时间:2012-10-08 05:45:09

标签: java serialization static-members

public class MySerializable implements Serializable{

    private int x=10;
    private static int y = 15;
    public static void main(String...args){
        AnotherClass a = new AnotherClass();
        AnotherClass b;
        //Serialize
        try {
            FileOutputStream fout = new FileOutputStream("MyFile.ser");
            ObjectOutputStream Oout = new ObjectOutputStream(fout);
            Oout.writeObject(a);
            System.out.println( a.toString());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //De-serialize
        try {
            FileInputStream fis = new FileInputStream("MyFile.ser");
            ObjectInputStream  Oin = new ObjectInputStream (fis); 
            b = (AnotherClass) Oin.readObject();
            System.out.println( b.toString());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }

    }
}

class AnotherClass  implements Serializable{  

    transient int x = 8;  
    static int y = 9;  

    @Override  
    public String toString() {  
        return "x : " + x + ", y :" + y;  
    }  
}

请告诉我静态变量是如何序列化的?

5 个答案:

答案 0 :(得分:11)

显然,静态变量可以序列化(但你不应该这样做),因为序列化保存实例的状态的过程,静态变量对所有实例都是通用的。他们没有说实例的状态,所以根本就没有意义。

假设您被允许序列化静态变量。然后,当您反序列化实例时,您将获得该变量的旧副本,此变量可能从那时起已更改。由于静态变量在类的所有实例之间共享,因此必须在此实例中反映来自任何实例的变量的更改。

因此,它们不应该被序列化,因为在这些条件下的变量可能会违反其作为静态变量的契约。

序列化: -

  • 不应序列化静态变量..

反序列化: -

  • 实例将获取随类加载的静态字段。因此,对该变量可能进行的任何更改也将对此实例负责..

答案 1 :(得分:2)

MySerializable类的当前输出低于

x : 8, y :9
x : 0, y :9

在这种情况下,静态变量在调用 toString()方法后被打印,此时它将从类级变量中读取值。

试试这个:

//Serialize阻止

之后,在MySerializable类中添加此行代码
AnotherClass.y = 5;

输出是:

x : 8, y :9
x : 0, y :5

这意味着静态变量不存储在文件中,它将通过toString()方法动态读取。

答案 2 :(得分:0)

- Serialization用于在序列化期间保存对象的状态,因此在反序列化期间,可以使用已保存的状态以便在堆上复活一个相同的对象。

- static变量可以serialized没有任何意义 ... ..

答案 3 :(得分:0)

静态变量不能也不能序列化。

您的问题似乎是基于这样一个事实:您在序列化之后看到静态变量中的相同值与序列化之前相同,但这不是由于序列化和恢复的值。

这种行为是因为该静态变量的静态初始值设定项将其设置为9,并且永远不会更改。

要验证静态变量未被序列化,您可以执行NPKR建议的更改,修改序列化和反序列化之间的静态字段,或者您可以执行以下操作:

运行该程序,然后注释掉执行序列化的位。因此,您将在磁盘上安装旧的序列化版本。

然后将静态字段的静态初始化程序更改为y = 5,然后再次运行程序:您将获得' x:0 y:5 as the output, because the value 9`的静态字段未恢复。

答案 4 :(得分:0)



import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

class TestJava implements Serializable{
    public static int k = 10;
    public int j=5;
public static void main(String[] args) {
    
    TestJava tj1= new TestJava();
    TestJava tj2;
    
    
        try{ //serialization
            FileOutputStream fos = new FileOutputStream("myclass.ser");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(tj1);
            oos.close();
            fos.close();
            System.out.println("object serielized 1..."+tj1.j);
            System.out.println("object serielized 2..."+tj1.k);
            System.out.println("object serielized 3..."+k);
            k=++k; // 'k' value incrementd after serialization
          } catch(FileNotFoundException fnfe){
             fnfe.printStackTrace();
          } catch(IOException ioex){
             ioex.printStackTrace();
          }
    
      
          try{ //deserialization
              FileInputStream fis = new FileInputStream("myclass.ser");
              ObjectInputStream ois = new ObjectInputStream(fis);
              tj2 = (TestJava) ois.readObject();
              ois.close();
              fis.close();
              System.out.println("object DEEEEserielized 1..."+tj2.j);
              System.out.println("object DEEEEserielized 2..."+tj2.k); 
              System.out.println("object DEEEEserielized 3..."+k); 
            // in deserialization 'k' value is shown as incremented. 
            // That means Static varialbe 'K' is not serialized.
            // if 'K' value is serialized then, it has to show old value before incrementd the 'K' value.
            } catch(FileNotFoundException fnfe){
              fnfe.printStackTrace();
            } catch(IOException ioex){
              ioex.printStackTrace();
            } catch(ClassNotFoundException CNFE){
              CNFE.printStackTrace();                   
           }
      }
}

/* Output of the above program
 
object serielized 1...5
object serielized 2...10
object serielized 3...10
object DEEEEserielized 1...5
object DEEEEserielized 2...11
object DEEEEserielized 3...11


*/