簡體   English   中英

對象的序列化(java)

[英]Serialization of Objects (java)

我有以下代碼:

import java.io.*;

public class TestSer {
    public static void main(String[] args) {
        SpecialSerial s = new SpecialSerial();
        try {
            ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("myFile"));
            os.writeObject(s); os.close();
            System.out.print(++s.z + " ");                         ...(1)
            ObjectInputStream is = new ObjectInputStream(new FileInputStream("myFile"));
            SpecialSerial s2 = (SpecialSerial)is.readObject();
            is.close();
            System.out.println(s2.y + " " + s2.z);
        } catch (Exception x) {
            System.out.println("exc");
        }
    }
}

class SpecialSerial implements Serializable {
    transient int y = 7;
    static int z = 9;
}

現在,當我運行代碼時,輸​​出為“ 10 0 10”。 但是為什么它是“ 10 0 10”而不是“ 10 0 0”? 我的意思是,當我反序列化對象時,y和z(分別是瞬時值和靜態值)應該返回為7和9,這是默認值(請在這一點上對我進行更正,因為我認為該對象在反序列化后得到的值)是默認值)。 語法“ ++ object.var”是什么意思(請參閱(1))。 是否與“ Object var ++”相同,即“ ++ sz”與“ s.z ++”相同?

由於z被聲明為staticSpecialSerial.z只有一個內存位置在內存中保存SpecialSerial.z的值。 該值優先於從文件反序列化的值。

添加:

private void writeObject(ObjectOutputStream oos) throws IOException {

    oos.defaultWriteObject();
    oos.writeInt(z);
    System.out.println("session serialized");
}

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {

    ois.defaultReadObject();
    z = ois.readInt();
}

確實使用從文件反序列化的z覆蓋了z的靜態值。

我不建議使用此技術,因為它可能會導致難以解決的問題。

現在,當我運行代碼時,輸​​出為“ 10 0 10”。 但是為什么它是“ 10 0 10”而不是“ 10 0 0”?

通過反序列化獲得對象時,瞬時變量將填充默認值。 但它共享給定類的JVM中存在的相同靜態變量 (或類變量)。 這就是為什么sz的值顯示為10的原因,這是當前運行的應用程序中z的現有值。

“ ++ sz”與“ s.z ++”相同嗎?

++sz使用preincrement運算符,這意味着先增加sz的值,然后再打印它。 s.z++使用postincrement運算符,這意味着先打印sz的值,然后再打印。

++ sz的意思是“先將sz加1,然后再使用它”,s.z ++的意思是“先使用sz再加1” ...為了回答您的主要問題,請回答以下簡單的問題:在您的類“ Special series”中您重寫“ isClose()”方法嗎? 可以輸入代碼嗎?

靜態變量與類相關聯。 因此,將z從9遞增到10后,只要程序正在運行,它將保持10。 同樣,瞬時變量y在反序列化期間未獲得任何賦值,因此其值為0(int變量的默認值)。

請記住,靜態變量在類級別。

對象序列化是在對象級別完成的。 因此,序列化和反序列化不會對靜態變量計數產生影響。

由於y是瞬態的,因此將在讀取對象后將其設置為默認值0。

System.out.print(++s.z + " "); 

輸出為10,因為您的對象位於內存中,序列化不會擦除瞬態字段,而只是在序列化時忽略它們。

 System.out.println(s2.y + " " + s2.z);

輸出為0和10,因為y是瞬態字段,所以為0,它不會保存在bean序列化中,因此在反序列化時它將獲得默認值,對於int而言,女巫為0。

10是因為z是靜態字段,那意味着它不與實例連接,序列化也不會擦除它。

等於:

s2.z and SpecialSerial.z
System.out.print(++s.z + " ");  

這會將z加1,然后將其打印出來。

並且因為z是靜態的,所以對於所有實例它都是相同的,因此反序列化之后它也將是10。 它不再是9,因為您在序列化之前增加了該值。

y為0,因為它聲明為瞬態,這意味着它將不屬於序列化對象。 因此,進行反序列化時不會設置任何值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM