免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開(kāi)通VIP
什么是writeObject 和readObject?可定制的序列化過(guò)程
這篇文章很直接,簡(jiǎn)單易懂。嘗試著翻譯一下 ,原文是What are writeObject and readObject? Customizing the serialization process.
在Java中使用Serialization相當(dāng)簡(jiǎn)單。如果你有一些對(duì)象想要進(jìn)行序列化,你只需實(shí)現(xiàn)Serializable接口。然后,你可以使用ObjectOutputStream將該對(duì)象保存至文件或發(fā)送到其他主機(jī)。所有的non-transient和non-static字段都將被序列化,并且由反序列化重構(gòu)造出一模一樣的對(duì)象聯(lián)系圖(譬如許多引用都指向該對(duì)象)。但有時(shí)你可能想實(shí)現(xiàn)你自己的對(duì)象序列化和反序列化。那么你可以在某些特定情形下得到更多的控制。來(lái)看下面的簡(jiǎn)單例子。
Java代碼 
class SessionDTO implements Serializable {
private static final long serialVersionUID = 1L;
private int data; // Stores session data
// Session activation time (creation, deserialization)
private long activationTime;
public SessionDTO(int data) {
this.data = data;
this.activationTime = System.currentTimeMillis();
}
public int getData() {
return data;
}
public long getActivationTime() {
return activationTime;
}
}
以下是序列化上述class到文件和其反序列化的主函數(shù)。
Java代碼 
public class SerializeTester implements Serializable {
public static void main(String... strings) throws Exception {
File file = new File("out.ser");
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(file));
SessionDTO dto = new SessionDTO(1);
oos.writeObject(dto);
oos.close();
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream(file));
SessionDTO dto = (SessionDTO) ois.readObject();
System.out.println("data : " + dto.getData()
+ " activation time : " + dto.getActivationTime());
ois.close();
}
}
類SessionDTO展現(xiàn)的是要在兩個(gè)服務(wù)器之間傳輸?shù)膕ession。它包含了一些信息在字段data上,該字段需要被序列化。但是它還有另外一個(gè)字段activationTime,該字段應(yīng)該是session對(duì)象第一次出現(xiàn)在任意服務(wù)器上的時(shí)間。它不在我們想要傳輸?shù)男畔⒅小_@個(gè)字段應(yīng)該在反序列化之后在賦值。進(jìn)一步來(lái)說(shuō),沒(méi)必要把它放在stream中在服務(wù)器中傳遞,因?yàn)樗紦?jù)了不必要的空間。
解決這種情況可以使用writeObject和readObject。有可能你們有一些人沒(méi)有聽(tīng)說(shuō)過(guò)它們,那是因?yàn)樗鼈冊(cè)谠S多Java書籍中給忽略了,而且它們們也不是眾多流行Java考試的一部分。讓我們用這些方法來(lái)重寫SessionDTO:
Java代碼 
class SessionDTO implements Serializable {
private static final long serialVersionUID = 1L;
private transient int data; // Stores session data
//Session activation time (creation, deserialization)
private transient long activationTime;
public SessionDTO(int data) {
this.data = data;
this.activationTime = System.currentTimeMillis();
}
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
oos.writeInt(data);
System.out.println("session serialized");
}
private void readObject(ObjectInputStream ois) throws IOException,
ClassNotFoundException {
ois.defaultReadObject();
data = ois.readInt();
activationTime = System.currentTimeMillis();
System.out.println("session deserialized");
}
public int getData() {
return data;
}
public long getActivationTime() {
return activationTime;
}
}
方法writeObject處理對(duì)象的序列化。如果聲明該方法,它將會(huì)被ObjectOutputStream調(diào)用而不是默認(rèn)的序列化進(jìn)程。如果你是第一次看見(jiàn)它,你會(huì)很驚奇盡管它們被外部類調(diào)用但事實(shí)上這是兩個(gè)private的方法。并且它們既不存在于java.lang.Object,也沒(méi)有在Serializable中聲明。那么ObjectOutputStream如何使用它們的呢?這個(gè)嗎,ObjectOutputStream使用了反射來(lái)尋找是否聲明了這兩個(gè)方法。因?yàn)镺bjectOutputStream使用getPrivateMethod,所以這些方法不得不被聲明為priate以至于供ObjectOutputStream來(lái)使用。
在兩個(gè)方法的開(kāi)始處,你會(huì)發(fā)現(xiàn)調(diào)用了defaultWriteObject()和defaultReadObject()。它們做的是默認(rèn)的序列化進(jìn)程,就像寫/讀所有的non-transient和 non-static字段(但他們不會(huì)去做serialVersionUID的檢查).通常說(shuō)來(lái),所有我們想要自己處理的字段都應(yīng)該聲明為transient。這樣的話,defaultWriteObject/defaultReadObject便可以專注于其余字段,而我們則可為這些特定的字段(譯者:指transient)定制序列化。使用那兩個(gè)默認(rèn)的方法并不是強(qiáng)制的,而是給予了處理復(fù)雜應(yīng)用時(shí)更多的靈活性。
你可以從這里這里讀到更多有關(guān)于序列化的知識(shí)。
自己再補(bǔ)充一些:
1.Write的順序和read的順序需要對(duì)應(yīng),譬如有多個(gè)字段都用wirteInt一一寫入流中,那么readInt需要按照順序?qū)⑵滟x值;
2.Externalizable,該接口是繼承于Serializable ,所以實(shí)現(xiàn)序列化有兩種方式。區(qū)別在于Externalizable多聲明了兩個(gè)方法readExternal和writeExternal,子類必須實(shí)現(xiàn)二者。Serializable是內(nèi)建支持的也就是直接implement即可,但Externalizable的實(shí)現(xiàn)類必須提供readExternal和writeExternal實(shí)現(xiàn)。對(duì)于Serializable來(lái)說(shuō),Java自己建立對(duì)象圖和字段進(jìn)行對(duì)象序列化,可能會(huì)占用更多空間。而Externalizable則完全需要程序員自己控制如何寫/讀,麻煩但可以有效控制序列化的存儲(chǔ)的內(nèi)容。
3.正如Effectvie Java中提到的,序列化就如同另外一個(gè)構(gòu)造函數(shù),只不過(guò)是有由stream進(jìn)行創(chuàng)建的。如果字段有一些條件限制的,特別是非可變的類定義了可變的字段會(huì)反序列化可能會(huì)有問(wèn)題??梢栽趓eadObject方法中添加條件限制,也可以在readResolve中做。參考56條“保護(hù)性的編寫readObject”和“提供一個(gè)readResolve方法”。
4.當(dāng)有非常復(fù)雜的對(duì)象需要提供deep clone時(shí),可以考慮將其聲明為可序列化,不過(guò)缺點(diǎn)也顯而易見(jiàn),性能開(kāi)銷。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Java Serializable
Serializable接口
Java 序列化的高級(jí)認(rèn)識(shí)
理解Java對(duì)象序列化
Java對(duì)象的序列化和反序列化實(shí)踐
java序列化(Serializable)的作用和反序列化
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服