假设我创建了一个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,是否应该在反序列化实例后保留它?
答案 0 :(得分:8)
以下是发生的事情:
如果您需要所描述的逻辑,则需要添加另一个静态变量,该变量计算创建的实例数,并使用您的自定义逻辑覆盖writeObject
和readObject
方法。
答案 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
。