Java 使用writeUnshared()在序列化过程中创建的对象数

Java 使用writeUnshared()在序列化过程中创建的对象数,java,serialization,io,Java,Serialization,Io,为了准备OCPJP7考试,我最近玩了一点序列化。 因此,我尝试序列化以下类: class TempClass implements Serializable { int secCounter; static int counter; { counter++; } { secCounter=counter; 然后,当我尝试使用以下命令

为了准备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个不同的对象,因此创建了3个对象。 但是,
secCounter
是一个实例变量,因此可以序列化,它的最终值是1而不是3。 1是我调用
new
关键字的次数,因此我假设在使用
obi.writeUnshared(object)
创建对象时,构造函数以不同的方式处理。 有人知道到底发生了什么吗?我知道静态变量没有序列化,但是在上面发布的代码中,我将值从静态变量复制到实例变量
secCounter
。 因此,再次检查成功序列化的
secCounter
的值不会得到预期的(至少对我来说)结果,而是1


提前谢谢

在反序列化期间,构造函数(或初始值设定项,如您的情况)不会执行,这是因为在反序列化对象时,您很可能期望对象的内部状态与原始对象的状态相同。运行初始值设定项或构造函数可能会产生“副作用”,如修改对象的内部状态

序列化期间创建的对象的快捷方式

Zero对象是在序列化过程中创建的,用于此问题

因此,创建了3个对象

writeUnshared()不创建任何对象。对象是在反序列化时创建的

但是,secCounter是一个实例变量,因此可以序列化,它的最终值是1而不是3

这证明了这一点。序列化时不创建对象

1是我调用new关键字的次数,因此我假设在使用obi.writeUnshared()创建对象时,构造函数以不同的方式处理


同样,此方法不会创建任何对象。没有调用构造函数。writeUnshared()中不会发生的是将“句柄”序列化到现有序列化对象。对象现在是序列化的,而不是一个句柄,该句柄将被反序列化为对以前反序列化实例的引用。

那么拥有一个新的(但相同的)对象有什么好处呢?只使用不创建克隆的writeObject(ob)不是更好吗?@Rollerball writeUnshared()也不“创建克隆”。您对该过程的理解存在严重缺陷。@EJP ok我应该用“克隆”这个词。。这并不意味着克隆与使用clone()方法相同,对此我深表歉意。但是,我指的是另一个对象,它的状态与writeObject而不是writeUnshared编写的“共享”对象的状态相同。如果使用
ObjectInputStream.readObject()
进行反序列化,您将拥有该对象的“克隆”(具有相同内部状态的对象),也许这就是writeUnshared的原因,“但老实说,我不确定这一点。”罗尔鲍尔你需要理解你所写的和你现在所说的意思之间的区别。发送时没有创建,因此也没有值更改。问题是当他读回它们时,而不是在序列化时。@EJP但是当我读回它们时,它们有不同的toString(),因此是不同的对象。。然而,即使是最后一次读取,secCounter的th值仍然是1。@Rolerball。您对何时发生“复制”或“克隆”或“构造”感到困惑。它不会在发送方发生,也不会通过构造发生,因此您希望执行的代码不会执行。@EJP但是最终的结果是我有3个不同的对象。我知道第一个是如何产生的,我用“新”做的。另外两个呢?它们什么时候被创建?我说的是那些用write.Unshared()序列化的,然后读回并放入引用的,我已经回答了。在反序列化期间。