我正在尝试找出 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/