java - Java 中静态反序列化的差异取决于序列化对象的时间

标签 java serialization static

我正在尝试找出 Java 中的(反/)序列化。

我读到,静态变量序列化。

为了弄清楚这一点,我做了一个小例子:

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;

public class SerialDemo {

    private static void writeFile() throws IOException, ClassNotFoundException {
        ObjectOutputStream o=new ObjectOutputStream(new FileOutputStream("foo"));
        Test test = new Test();
        o.writeObject(test);
        o.flush();
    }

    private static Test readFile() throws FileNotFoundException, IOException, ClassNotFoundException {
        ObjectInputStream in=new ObjectInputStream(new FileInputStream("foo"));
        return (Test) in.readObject();
    }
}
class Test implements Serializable{
    static Integer i;
    public Test(){
        i = 10;
    }
}

为什么这两个主要方法的运行存在差异?

第一个版本: 在一次运行中序列化和反序列化

public static void main(String[] args)  {

        try {
            // Serialization
            writeFile();
            // Deserialization
            Test deserializedFile = readFile();
            System.out.println(deserializedFile.i);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

输出10。但为什么?我认为 Integer i 的值没有序列化,因为它是静态的。

第二个版本: 在两次不同的运行中进行序列化和反序列化。

如果我第一次运行:

public static void main(String[] args)  {
        try {
            // Serialization
            writeFile();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

第二次运行时:

public static void main(String[] args)  {
        try {
            // Deserialization
            Test deserializedFile = readFile();
            System.out.println(deserializedFile.i);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

它输出 null,正如我在第一个版本中所建议的那样。

区别在哪里?!

最佳答案

简单:它是一个静态变量。当您使用构造函数创建一个实例时,它会在第一个示例中初始化!

在第二个示例中,该构造函数从未被调用,该字段保持为空!

这就是全部内容了。正如您自己所说:静态字段写入该文件中。在您的两个示例中唯一重要的是一个版本调用构造函数,而另一个版本则不调用。

除此之外,这里还有另一个误解:您编写deserializedFile.i...这是概念上错误的。您应该使用Test.i来代替。静态变量对于所有实例都是相同的,它们的所属范围是 Test 类,而不是该类的某个实例!

郑重声明:deserializedFile 是一个非常具有误导性的名称。该变量表示反序列化的测试对象。它不是到一个文件!名称应该说明其含义,而不是撒谎。这个名字很谎言!

关于java - Java 中静态反序列化的差异取决于序列化对象的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54006659/

相关文章:

java - GLSL 中奇怪的灯光

java - 在javafx中将文本放在一个圆圈中

java - Lucene StoredField 与 StringField 性能对比

C# 用户控件设计时序列化

命令行参数

java - 继承的静态成员的意外行为

java - 多态性和静态方法

java - 如果用户尚未安装 JRE,我如何提示用户安装 JRE?

c# - 是否可以将 System.Text.Encoding 类从 JSON 反序列化为 C# 中的代码?

c++ - vector 序列化