首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java中静态反序列化的区别取决于对象序列化时

Java中静态反序列化的区别取决于对象序列化时
EN

Stack Overflow用户
提问于 2019-01-02 12:46:33
回答 3查看 43关注 0票数 2

我正在设法找出Java中的(de/)序列化。

我读过,static变量没有序列化。

为了解决这个问题,我举了一个小例子:

代码语言:javascript
复制
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;
    }
}

为什么这两种主要方法的运行有区别?

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

代码语言:javascript
复制
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的值没有序列化,因为它是static

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

如果我第一次跑:

代码语言:javascript
复制
public static void main(String[] args)  {
        try {
            // Serialization
            writeFile();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

在第二轮中:

代码语言:javascript
复制
public static void main(String[] args)  {
        try {
            // Deserialization
            Test deserializedFile = readFile();
            System.out.println(deserializedFile.i);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

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

有什么区别?!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-01-02 12:55:40

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

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

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

除此之外,这里还有另一个误解:您编写反序列化文件。这在概念上是错误的,。你应该用Test.i代替。静态变量对于所有实例都是相同的,它们拥有的作用域是Test类,而不是该类的某些实例!

我要说的是: deserializedFile是一个非常误导的名字。该变量表示反序列化的Test对象。这不是文件!名字应该说出来,而不是撒谎。这个名字很重要!

票数 2
EN

Stack Overflow用户

发布于 2019-01-02 12:54:44

在第一个示例中,值10仍然位于静态变量i中,因为它在相同的运行中。它实际上不是由readFile()方法加载的。

在第二个示例中,该值在第一次运行中仍然是10,但在第二次运行中,它是默认值null (尚未调用构造函数),调用readFile()并不实际将值加载到i中。

尝试在第一个示例中在deserializedFile.i = null;之前调用readFile(),您将注意到与第二个示例中的行为相同。

票数 2
EN

Stack Overflow用户

发布于 2019-01-02 12:55:36

如预期的那样工作。在您的第一次运行中,i变量没有序列化。您看到的是在测试构造函数中设置的值,因为它是静态的,所以相同类的所有对象的值都是相同的。

在第二次运行中,您不会通过构造函数创建Test类,因此不会设置值。反序列化没有调用Test构造函数,也没有反序列化i值,因此您可以看到正确的输出空值。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54006659

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档