我最近在序列化方面做了一些尝试,以便为OCPJP7考试做好准备。 因此我尝试序列化以下类:
class TempClass implements Serializable {
int secCounter;
static int counter;
{
counter++;
}
{
secCounter=counter;
然后当我尝试使用以下内容将对象写入FileOutputStream
时:
TempClass temp = new TempClass();
ObjectOutputStream obi = new ObjectOutputStream(new FileOutputStream(file));
obi.writeObject(temp);
obi.writeUnshared(temp);
obi.writeUnshared(temp);
因此,当我用ObjectInputStream
读回它时,我得到了3个不同的对象,因此创建了3个对象。
但是,secCounter
的最终值,即一个实例变量,因此可以序列化,是1而不是3。
1是我调用new
关键字的时间,所以我认为当使用obi.writeUnshared(object)
创建对象时,构造函数会以不同的方式处理。
有人知道究竟发生了什么吗?我知道静态变量没有序列化,但是在上面发布的代码中我将值从静态变量复制到实例变量secCounter
。
因此,最终检查成功序列化的secCounter
的值将不会得到我预期的(至少对我而言)结果,但是1。
提前致谢。
答案 0 :(得分:2)
出于此问题的目的,在序列化期间会创建序列化期间创建的对象的数量......
零 对象。
因此创建了3个对象。
writeUnshared()没有创建任何对象。在反序列化时创建对象。
然而,secCounter的最终值,即一个实例变量,因此可以序列化,是1而不是3。
证明了这一点。序列化时不会创建任何对象。
1是我调用new关键字的时间,所以我认为当使用obi.writeUnshared()
创建对象时,构造函数会以不同的方式处理
再一次,此方法不会创建任何对象。没有调用构造函数。 writeUnshared()中不的内容是对现有序列化对象的“句柄”的序列化。现在的对象是序列化的,而不是将被反序列化为对先前反序列化的实例的引用的句柄。
答案 1 :(得分:0)
在反序列化期间,不执行构造函数(或初始化程序,如在您的情况下),这是因为当您反序列化对象时,您可能期望对象的内部状态与原始对象的状态相同。运行初始化程序或构造函数可能会产生“副作用”,例如修改对象的内部状态。