[英]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
被聲明為static
, SpecialSerial.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.