反序列化对象后静态变量的值是多少?

发布于 2024-08-15 13:29:05 字数 366 浏览 3 评论 0原文

假设我创建了一个 B 类的实例,它有一个静态变量 x,在 B 类声明中分配了值 3。在 main() 方法中,我这样做:

B b = new B();
b.x = 7; //allowed to use an instance to set the static member value

在此之后,b 被序列化,然后反序列化。然后,出现以下行:

System.out.println ("static: " + b.x);

值是多少? 7还是3?

我知道静态变量没有序列化,但是,由于整个类只有一份静态成员的副本,并且该值设置为7,是否应该在反序列化实例后保留它?

Let's say that I create an instance of class B, which has an static variable x, assigned with a value of 3 in the class B declaration. In the main() method, I do this:

B b = new B();
b.x = 7; //allowed to use an instance to set the static member value

After this, b is serialized and then de-serialized. Then, the following line occurs:

System.out.println ("static: " + b.x);

What's the value? 7 or 3?

I know static variables are not serialized, however, since there is only one copy of the static member for the whole class, and the value is set to 7, should it be preserved after de-serializing an instance?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

小姐丶请自重 2024-08-22 13:29:05

发生的情况如下:

  1. 静态初始值设定项将值设置为 3。
  2. 实例构造函数将值设置为 7。
  3. 序列化不知道静态变量,并且将其忽略。
  4. 反序列化不知道静态变量并且它被忽略。
  5. 如果程序一直在运行,或者程序被关闭并重新启动,则值仍然为 7(来自构造函数中发生的更改),静态初始化程序会将其设置为 3,并且反序列化不会更改它。

如果您想要您描述的逻辑,您需要添加另一个静态变量来计算创建的实例数量,并使用您的自定义逻辑覆盖 writeObjectreadObject 方法。

Here's what happens:

  1. Static initializer sets the value to 3.
  2. Instance constructor sets the value to 7.
  3. Serialization is unaware of the static variable and it is ignored.
  4. De-serialization is unaware of static variable and it is ignored.
  5. Value is still 7 (from the change that occurred in the constructor) if the program has been running all along, or if the program was shutdown and restarted, the static initializer will have set it to 3 and de-serialization did not change it.

If you want the logic you describe, you need to add another static variable which counts the number of instances created and override the writeObject and readObject methods with your custom logic.

月亮是我掰弯的 2024-08-22 13:29:05

如果您在 JVM 的同一个实例中反序列化它,您的第二个代码段将返回 7。这是因为 bx 的值设置为 7。这并没有改变,因为B 的实例已被序列化并反序列化。

如果序列化该对象,关闭 JVM,启动一个新的 JVM,然后反序列化该对象(除了静态初始化之外不在任何地方设置 bx),bx 的值将为 3。

If you deserialize it in the same instance of the JVM, your second snippet will return 7. This is because the value of b.x is set to 7. That hasn't changed because an instance of B was serialized and deserialized.

If you serialize the object, shutdown the JVM, bring up a new JVM, and then deserialize the object (without setting b.x anywhere other than the static initialization), the value of b.x will be 3.

国产ˉ祖宗 2024-08-22 13:29:05

使用以下代码对内存流进行序列化、反序列化和对象化:

package com.example.serialization;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable; 
import junit.framework.TestCase;


public class SerializationTest extends TestCase {
    public void testStaticValueAfterSerialization() {
       B b = new B();
       b.x = 7; //allowed to use an instance to set the static member value

       B deserializedB = copyObject(b);
       assertEquals("b.x should be 7 after serialization", 7, deserializedB.x);
    }

    private <T extends Serializable> T copyObject(final T source) {
        if (source == null)
                throw new IllegalArgumentException("source is null");
        final T copy;
        try {
            copy = serializationClone(source);
            } catch (Exception e) {
                // (optional) die gloriously!
            throw new AssertionError("Error copying: " + source, e);
        }    
            return copy;
    }

    private <T extends Serializable> T serializationClone(final T source)
        throws IOException, ClassNotFoundException {
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    ObjectOutputStream outputStream = new ObjectOutputStream(byteStream);

            // 1. serialize the object to the in-memory output stream
        outputStream.writeObject(source);

        ObjectInputStream inputStream = new ObjectInputStream(
                new ByteArrayInputStream(byteStream.toByteArray()));

        // 2. deserialize the object from the in-memory input stream
        @SuppressWarnings("unchecked")
            final T copy = (T) inputStream.readObject();

        return copy; // NOPMD : v. supra
    }
}

创建该类后,使用 JUnit 运行程序运行它并查看测试是否通过!如果您愿意,可以在一个测试用例中将结果写入文件。然后在另一个测试用例中,从文件中读取结果!

Use the following code to serialize and deserialize and object to / from an in-memory stream:

package com.example.serialization;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable; 
import junit.framework.TestCase;


public class SerializationTest extends TestCase {
    public void testStaticValueAfterSerialization() {
       B b = new B();
       b.x = 7; //allowed to use an instance to set the static member value

       B deserializedB = copyObject(b);
       assertEquals("b.x should be 7 after serialization", 7, deserializedB.x);
    }

    private <T extends Serializable> T copyObject(final T source) {
        if (source == null)
                throw new IllegalArgumentException("source is null");
        final T copy;
        try {
            copy = serializationClone(source);
            } catch (Exception e) {
                // (optional) die gloriously!
            throw new AssertionError("Error copying: " + source, e);
        }    
            return copy;
    }

    private <T extends Serializable> T serializationClone(final T source)
        throws IOException, ClassNotFoundException {
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    ObjectOutputStream outputStream = new ObjectOutputStream(byteStream);

            // 1. serialize the object to the in-memory output stream
        outputStream.writeObject(source);

        ObjectInputStream inputStream = new ObjectInputStream(
                new ByteArrayInputStream(byteStream.toByteArray()));

        // 2. deserialize the object from the in-memory input stream
        @SuppressWarnings("unchecked")
            final T copy = (T) inputStream.readObject();

        return copy; // NOPMD : v. supra
    }
}

After creating that class, run it with a JUnit runner and see if the test passes! If you like, you can write the result to a file in one test case. Then in another test case, read the result from a file!

叫思念不要吵 2024-08-22 13:29:05

由于静态初始化程序仅运行一次,因此该值为 7

Since static initializers run exactly once, the value is 7.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文