当前位置: 首页 > 面试题库 >

Java:为什么反序列化不调用构造函数?最好的解决方法是什么?

郝杰
2023-03-14
问题内容

Java 1.5 的Java序列化规范说:

对于可序列化的对象,运行第一个不可序列化超类型的no-
arg构造函数。对于可序列化的类,将字段初始化为适合其类型的默认值。然后,通过调用特定于类的readObject方法来恢复每个类的字段,如果未定义这些字段,则通过调用defaultReadObject方法来恢复它们。请注意,在反序列化期间,不会为可序列化的类执行字段初始化程序和构造函数。

但是,这意味着如果将静态变量(例如计数器变量)放入类中,则不会像通常那样进行更新:

class Foo {
    static int t;

    public Foo() {
        t++;
    }
}

public class Bar extends Foo implements Serializable {
    static int t;

    public Bar() {
        t++;
    }
}

在这种情况下,如果对的一个实例进行Bar反序列化,则for的计数器Foo是正确的,for的计数器Bar是一对一的。

我想知道为什么反序列化不调用构造函数?由于这似乎会提高速度,但可能会导致潜在的问题。可以很容易地将编译器设计为生成“静态构造函数”,该“静态构造函数”仅更新将要更新的静态变量,并且在加载类时不依赖外部信息。

另外,我想知道避免这种情况的最佳方法是什么?我能想到的解决方案是将反序列化与对静态变量的操作打包在一起。

感谢您的任何提前输入!


问题答案:

反序列化不会调用构造函数,因为它的目的是在序列化对象时表达对象的状态,运行构造函数代码可能会干扰它。



 类似资料:
  • 问题内容: 在Java中,为什么从构造函数中调用方法被认为是不好的做法?如果该方法计算量大,是否特别糟糕? 问题答案: 首先,通常在构造函数中调用方法没有问题。这些问题特别涉及调用构造函数的类的可重写方法以及将对象的引用传递给其他对象的方法(包括构造函数)的特殊情况。 避免重载方法和“泄漏” 的原因可能很复杂,但它们基本上都与防止使用未完全初始化的对象有关。 避免调用可覆盖的方法 避免在构造函数中

  • 问题内容: 是仅在继承还是大多数情况下才是正确的? 问题答案: 这是真的。 因为二传手总是方法。如果您的课程不是,那么就会出现外来方法调用的问题。这不是线程安全的,即称为转义引用。因此,从构造函数中,如果要调用方法,则应为或。其他对象将不会发生,这会在实际系统中导致许多错误。 除了上述内容之外,我们永远不要从中调用method,因为 如果该类旨在继承,则Constructor不得直接或间接调用可重

  • 本文向大家介绍请解释Java中的概念,什么是构造函数?什么是构造函数重载?什么是复制构造函数?相关面试题,主要包含被问及请解释Java中的概念,什么是构造函数?什么是构造函数重载?什么是复制构造函数?时的应答技巧和注意事项,需要的朋友参考一下 考察点:JAVA构造函数 当新对象被创建的时候,构造函数会被调用。每一个类都有构造函数。在程序员没有给类提供构造函数的情况下,Java编译器会为这个类创建一

  • 问题内容: 我是Java的初学者,我想以一种简单的方式知道为什么您应该使用参数化构造函数而不是编译器提供的默认构造函数。 谢谢 问题答案: 默认构造函数将您的对象可能具有的所有属性设置为0,false等。如果要立即设置属性,则可以使用参数化的构造函数。当然,也可以使用您自己的构造函数为您提供在创建对象之前(技术上而言)执行代码的选项。 顺便说一句:“默认值不会为属性设置任何值”的答案是错误的。例如

  • 根据我的理解,当创建了临时对象时,将调用move构造函数。这里,函数返回一个临时对象,但我的程序没有打印来自移动构造函数的消息:

  • 问题内容: 我在使用Jackson来反序列化JSON字符串时遇到问题(但是我没有问题将对象序列化为JSON)。 下面,我介绍我使用的类。当我接收到JSON字符串(已在其他地方进行序列化并通过Web服务检索的ProtocolContainer)并想反序列化时,就会出现问题: JSON字符串: {“ DataPacketJSONString”:null,“ DataPacketType”:“ MyPa