首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >反序列化对象后静态变量的值是什么?

反序列化对象后静态变量的值是什么?
EN

Stack Overflow用户
提问于 2009-12-19 00:10:46
回答 4查看 5.1K关注 0票数 1

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

代码语言:javascript
复制
B b = new B();
b.x = 7; //allowed to use an instance to set the static member value

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

代码语言:javascript
复制
System.out.println ("static: " + b.x);

值是多少?7还是3?

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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-12-19 00:15:23

下面是发生的事情:

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

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

票数 8
EN

Stack Overflow用户

发布于 2009-12-19 00:14:53

如果在JVM的同一实例中反序列化它,那么第二个代码片段将返回7。这是因为b.x的值被设置为7。这并没有改变,因为B的一个实例被序列化和反序列化了。

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

票数 7
EN

Stack Overflow用户

发布于 2009-12-19 01:05:07

使用以下代码对内存中的流进行序列化和反序列化,并将对象传入/传出:

代码语言:javascript
复制
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运行器运行它,并查看测试是否通过!如果您愿意,可以在一个测试用例中将结果写到一个文件中。然后在另一个测试用例中,从文件中读取结果!

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

https://stackoverflow.com/questions/1929130

复制
相关文章

相似问题

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