java - 新对象 : new operator vs serialization

标签 java serialization

据我所知,在 Java 中基本上有两种创建全新对象的方法:1) 使用 new 运算符和 2) 通过序列化(用于深度复制,例如)。所有其他对象操作(例如分配)都处理对现有对象的引用。但是上述两种方式在内在逻辑上有什么区别呢?似乎一个区别是序列化以某种方式不使用构造函数方法。我对吗?还有其他区别吗?

我所说的“内部逻辑”是指编译器(或任何处理它的人)如何逐步创建对象,它使用什么算法,为此使用什么方法等等。更像是玛格丽特·布鲁姆 (Margaret Bloom) 在她的回答中所写的内容,但更详细。

进一步混淆澄清:

那么在反序列化过程中,对象的副本是否正确:

class Class1 {
    static ARRAY_LENGTH = 10;
    public class1() {
        int[] anArray = new int[ARRAY_LENGTH];
        anArray[0] = 5;
        ...
        anArray[9] = -2;
    }
}

将包含以其他方式创建的数组的副本(如何?因为没有调用构造函数)?此外,尽管原始数组(在序列化之前)是使用 static 字段(在序列化过程中丢失)创建的,但它的反序列化副本仍然与原始数组相同?

最佳答案

序列化和 new 运算符是完全不同的东西,尽管它们都会导致对新分配对象的引用。

您可以在 Java Language Specification15.9.4 类实例创建表达式的运行时求值 章中找到有关 new 运算符的详细信息。 .

At run time, evaluation of a class instance creation expression is as follows.
[...]
Next, space is allocated for the new class instance.
[...] The new object contains new instances of all the fields declared in the specified class type and all its superclasses.
[...] Next, the actual arguments to the constructor are evaluated, left-to-right. [...]
Next, the selected constructor of the specified class type is invoked. This results in invoking at least one constructor for each superclass of the class type.
The value of a class instance creation expression is a reference to the newly created object of the specified class. Every time the expression is evaluated, a fresh object is created.

编辑我的
长话短说,new 为新对象分配空间(特别是为其字段分配空间),使用默认值初始化其字段并调用选定的构造函数。


Java Serialization完全是另一回事。

The ability to store and retrieve JavaTM objects is essential to building all but the most transient applications. The key to storing and retrieving objects in a serialized form is representing the state of objects sufficient to reconstruct the object(s). Emphasis mine

这意味着序列化旨在允许程序员将对象状态保存到持久介质中(在 Java 中抽象为 stream)和 read them back .

因此,反序列化不会调用构造函数,因为对象状态是通过从流中读出而自动恢复的。不过,您可以覆盖默认行为。

Reading an object from the ObjectInputStream is analogous to creating a new object. Just as a new object's constructors are invoked in the order from the superclass to the subclass, an object being read from a stream is deserialized from superclass to subclass. The readObject or readObjectNoData method is called instead of the constructor for each Serializable subclass during deserialization.

强调我的


说到这里,我想强调的是,从概念的角度来看,使用 new 和序列化是完全无关的事情。
在第一种情况下,您正在创建自己的新对象,在后一种情况下,您正在读取以前保存的对象(可能由其他人保存)。

尽管它们的最终结果可以被认为是相似的,但在您的脑海中,您应该清楚地区分两者。

关于java - 新对象 : new operator vs serialization,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36833782/

相关文章:

java - 我如何从 Android SDK 解析 PHP 数组?

java - 如何从 JFrame 切换到 java 类?

javascript - 为什么数组偏移量被视为自己的属性?

serialization - Erlang序列化库

java - Date 的自定义 gson 反序列化程序永远不会被调用

java - 我该如何进行这个单元测试?

java - 大 O 符号 O(NM) 或 (N^2)

java - Bazel:具有 JNI 依赖项的 Java 应用程序

c# - 在 C# 的反序列化过程中创建指向父对象的指针

java - 对象反序列化 - 从序列化对象中获取 int 数组