Java序列化接口的作用总结
一個(gè)對(duì)象有對(duì)應(yīng)的一些屬性,把這個(gè)對(duì)象保存在硬盤(pán)上的過(guò)程叫做”持久化”.
把堆內(nèi)存中的對(duì)象的生命周期延長(zhǎng),存入硬盤(pán),做持久化操作.當(dāng)下次再需要這個(gè)對(duì)象的時(shí)候,我們不用new了,直接從硬盤(pán)中讀取就可以了.(存儲(chǔ)到硬盤(pán)是一個(gè)文件,不需要我們?nèi)ソ馕?如果用記事本打開(kāi)解析會(huì)出現(xiàn)亂碼,解析要用特定的方式,不用我們管. 我們只需要讀取).
把對(duì)象存儲(chǔ)到硬盤(pán)上的一個(gè)文件中,這個(gè)文件的標(biāo)準(zhǔn)擴(kuò)展名是(.object).
在很多框架中就會(huì)有這種.object結(jié)尾的文件,因?yàn)楹芏鄬?duì)象都不創(chuàng)建,創(chuàng)建起來(lái)太麻煩,直接讀取,而且有些對(duì)象的值你不知道,框架封存在.object文件中,直接讀取這個(gè)文件中的這個(gè)值就行了,不需要傳這個(gè)值.
1 import java.io.Serializable;2 /*3 * Serializable:用于給被序列化的類(lèi)加入ID號(hào)。4 * 用于判斷類(lèi)和對(duì)象是否是同一個(gè)版本。 5 */6 public class Person implements Serializable/*標(biāo)記接口*/ {7 /**8 * transient:非靜態(tài)數(shù)據(jù)不想被序列化可以使用這個(gè)關(guān)鍵字修飾。 9 */ 10 private static final long serialVersionUID = 9527l; 11 // private transient String name; 12 private String name; 13 // private static int age; 14 private int age; 15 16 public Person(String name, int age) { 17 super(); 18 this.name = name; 19 this.age = age; 20 } 21 public String getName() { 22 return name; 23 } 24 public void setName(String name) { 25 this.name = name; 26 } 27 public int getAge() { 28 return age; 29 } 30 public void setAge(int age) { 31 this.age = age; 32 } 33 } 1 public class ObjectStreamDemo {2 /**3 * @param args4 * @throws IOException 5 * @throws ClassNotFoundException 6 */7 public static void main(String[] args) throws IOException, ClassNotFoundException {8 //writeObj();9 readObj(); 10 } 11 public static void readObj() throws IOException, ClassNotFoundException { 12 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.object")); 13 //對(duì)象的反序列化。 14 Person p = (Person)ois.readObject(); 15 System.out.println(p.getName()+":"+p.getAge()); 16 ois.close(); 17 } 18 19 public static void writeObj() throws IOException, IOException { 20 21 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.object")); 22 //對(duì)象序列化。 被序列化的對(duì)象必須實(shí)現(xiàn)Serializable接口。 23 oos.writeObject(new Person("小強(qiáng)",30)); 24 oos.close(); 25 } 26 }序列號(hào)的作用:舉個(gè)例子,當(dāng)你一開(kāi)始對(duì)這個(gè)person類(lèi)進(jìn)行序列化的時(shí)候用的是private類(lèi)型序列化的,但是你在反序列化之前,把這個(gè)private改成了public.這樣反序列化讀取的時(shí)候就會(huì)報(bào)出異常.
Exception in thread "main" java.io.InvalidClassException: cn.itcast.serializable.Person; local class incompatible: stream classdesc serialVersionUID = 9527, local class serialVersionUID = 7915096815468332737?
就是關(guān)于前后這個(gè)Person類(lèi)的版本號(hào)不統(tǒng)一.如果加上設(shè)定一個(gè)版本號(hào),那么經(jīng)過(guò)上面的修改也是可以反序列化的.
?
@throws?ClassNotFoundException
如果只有obj.object 這個(gè)文件能不能把其中的對(duì)象Person取出來(lái),因?yàn)槿魏螌?duì)象在堆內(nèi)存中創(chuàng)建都必須依賴(lài)于該對(duì)象所屬的類(lèi)文件(class文件),如果僅僅給了obj.object,這個(gè)里面有Person對(duì)象的字節(jié)碼,可是取出的時(shí)候你內(nèi)存中并沒(méi)有Person.class文件,沒(méi)有,所以取不出來(lái),所以必須要有obj.object文件和Person.class文件.(所以有一個(gè)ClassNotFound異常)
?
類(lèi) ObjectInputStream
ObjectInputStream 對(duì)以前使用 ObjectOutputStream 寫(xiě)入的基本數(shù)據(jù)和對(duì)象進(jìn)行反序列化。
這句話(huà)的意思就是ObjectInputStream只能讀取ObjectOutputStream的.
ObjectOutputStream 和 ObjectInputStream 分別與 FileOutputStream 和 FileInputStream 一起使用時(shí),可以為應(yīng)用程序提供對(duì)對(duì)象圖形的持久存儲(chǔ)。
?
序列化就是按照順序排列
Serializable就是一個(gè)標(biāo)記,(要想實(shí)現(xiàn)序列化必須有這個(gè)標(biāo)記)
對(duì)象的默認(rèn)序列化機(jī)制寫(xiě)入的內(nèi)容是:對(duì)象的類(lèi),類(lèi)簽名,以及非瞬態(tài)和非靜態(tài)字段的值。(因?yàn)殪o態(tài)static的東西在方法區(qū).)
?
使用時(shí)候:對(duì)某些特點(diǎn)的對(duì)象,比如數(shù)據(jù)庫(kù)連接對(duì)象,存儲(chǔ)特定數(shù)據(jù)的對(duì)象 ,這樣對(duì)象你不想創(chuàng)建他們,想存儲(chǔ)起來(lái),讓他們的生命周期延長(zhǎng),可以把他們放在硬盤(pán)當(dāng)中.每次系統(tǒng)啟動(dòng)的時(shí)候都到.object中讀取對(duì)象和里面的數(shù)據(jù),這個(gè)時(shí)候就可以把他們序列化來(lái)完成.
僅僅是把對(duì)象從堆內(nèi)存存儲(chǔ)到了硬盤(pán)上.
?
接口 Serializable
序列化運(yùn)行時(shí)使用一個(gè)稱(chēng)為 serialVersionUID 的版本號(hào)與每個(gè)可序列化類(lèi)相關(guān)聯(lián). 該序列號(hào)在反序列化過(guò)程中用于驗(yàn)證序列化對(duì)象的發(fā)送者和接收者是否為該對(duì)象加載了與序列化兼容的類(lèi)。(當(dāng)一個(gè)對(duì)象進(jìn)行序列化的時(shí)候,給該類(lèi)分配一個(gè)id號(hào).這個(gè)id號(hào)可以用來(lái)驗(yàn)證.你給給我的文件存儲(chǔ)的對(duì)象和你給我的類(lèi)到底是不是同一版本的啊….)
?
這個(gè)ID號(hào)是根據(jù)類(lèi)的特征和類(lèi)的簽名算出來(lái)的.為什么ID號(hào)那么長(zhǎng),是因?yàn)闉榱吮苊庵貜?fù).
所以Serializable是給類(lèi)加上id用的. 用于判斷類(lèi)和對(duì)象是否是同一個(gè)版本。
?
如果可序列化類(lèi)未顯式聲明 serialVersionUID,則序列化運(yùn)行時(shí)將基于該類(lèi)的各個(gè)方面計(jì)算該類(lèi)的默認(rèn) serialVersionUID 值. 原因是計(jì)算默認(rèn)的 serialVersionUID 對(duì)類(lèi)的詳細(xì)信息具有較高的敏感性,根據(jù)編譯器實(shí)現(xiàn)的不同可能千差萬(wàn)別,這樣在反序列化過(guò)程中可能會(huì)導(dǎo)致意外的?InvalidClassException。
?
在學(xué)web的時(shí)候一些類(lèi)就需要實(shí)現(xiàn)序列化接口,因?yàn)榉?wù)器就會(huì)對(duì)你的對(duì)象進(jìn)行臨時(shí)本地存儲(chǔ).它怕服務(wù)器崩了的以后,你的會(huì)話(huà)都被消失了.所以存儲(chǔ)在了硬盤(pán)上,你重新啟動(dòng)服務(wù)器會(huì)恢復(fù)之前的會(huì)話(huà),恢復(fù)對(duì)象,你之前運(yùn)行的東西都在.
//====================================================================
具體示例可以看我的如下博文(轉(zhuǎn)載+總結(jié)):
http://www.cnblogs.com/DreamDrive/p/5412931.html
轉(zhuǎn)載于:https://www.cnblogs.com/writeLessDoMore/p/6733449.html
總結(jié)
以上是生活随笔為你收集整理的Java序列化接口的作用总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: JavaScript的理解记录(6)
- 下一篇: Java读取Propertity文件