静态成员序列化



我读到"序列化不适用于静态元素" - 但下面的简单示例告诉我并非如此。

class superparent implements Serializable {
    int data = 0;
    public superparent(int data) {
        this.data = data;
    }
    public int getdata() {
        return data;
    }
}
public class statichost implements Serializable {
    int member = 0;
    public static superparent s = new superparent(20);
    public statichost(int data) {
        this.member = data;
    }
    public static void main(String[] args) {
        statichost c = new statichost(6);
        try {
            FileOutputStream fs = new FileOutputStream("testSer.ser");
            ObjectOutputStream os = new ObjectOutputStream(fs);
            os.writeObject(c);
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            FileInputStream fis = new FileInputStream("testSer.ser");
            ObjectInputStream ois = new ObjectInputStream(fis);
            c = (statichost) ois.readObject();
            ois.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("after: contained data is " + c.s.getdata());
    }
}

输出打印 20,而我按照上面的陈述期望为 0。我错过了什么吗?

这是因为您的int data=0;不是类superparent的静态成员。

我还想指出,类名应该以大写字母开头,如果你忘记了这个建议

这里

没有什么特别的事情发生。您已经为类statichost声明了一个静态成员变量。当 JVM 装入类时,此变量将初始化,而不管是什么触发了类的装入。

序列化

和反序列化 statichost 实例与静态字段无关,因为它们与您的类相关联,而不是与您的实例相关联。如果要对此进行测试,请将序列化和反序列化分解为不同的块,并执行以下步骤:

  • 序列化statichost实例
  • 更改类,以便使用 15 而不是 20 初始化superparent
  • 反序列化statichost实例

如果序列化静态字段,则c.s.getdata()报告为 20,但它将报告 15。

我认为

您的测试代码无法验证这种情况。因为 20 是由类初始化中的public static superparent s=new superparent(20);设置的,所以在类加载时,JVM 总是将其设置为 20。

如果希望初始数据为0并检查数据修改为20无法序列化,请尝试

  1. 使用 public static superparent s=new superparent(0); 而不是 20 作为初始值。
  2. 注释掉第一次执行的 readObject try-catch 块,并在第一个 try-catch 块中添加修改代码 c.s.data=20 并写入文件,然后执行代码。
  3. 注释掉第二次执行的 writeObject try-catch 块,并执行读取对象再次编码。然后你可以看到20不能序列化成文件,0是打印的。

最新更新