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

时间:2009-12-18 16:10:46

标签: java serialization static member

假设我创建了一个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,是否应该在反序列化实例后保留它?

4 个答案:

答案 0 :(得分:8)

以下是发生的事情:

  1. 静态初始值设定项将值设置为3。
  2. 实例构造函数将值设置为7。
  3. 序列化不知道静态变量,它会被忽略。
  4. 反序列化不知道静态变量,它会被忽略。
  5. 如果程序一直在运行,或者如果程序已关闭并重新启动,则值仍为7(来自构造函数中发生的更改),静态初始化程序将其设置为3并且反序列化不会改变它。
  6. 如果您需要所描述的逻辑,则需要添加另一个静态变量,该变量计算创建的实例数,并使用您的自定义逻辑覆盖writeObjectreadObject方法。

答案 1 :(得分:7)

如果在JVM的同一个实例中对其进行反序列化,则第二个代码段将返回7.这是因为bx的值设置为7.由于 B的实例被序列化和反序列化。

如果你序列化对象,关闭JVM,启动一个新的JVM,然后反序列化对象(除了静态初始化之外不设置b.x),b.x的值将是3。

答案 2 :(得分:1)

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

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运行程序运行它,看看测试是否通过!如果您愿意,可以在一个测试用例中将结果写入文件。然后在另一个测试用例中,从文件中读取结果!

答案 3 :(得分:0)

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