保存對象
串流(Stream)
- 串流分為連接用串流(connnection streams)和鏈接用串流(chain streams)识补,連接用串流通常來連接來源或者目的地富俄, typically a file, network socket connection, or the console. 鏈接用串流不能用來連接源或者目的地。Chain streams cannot connect to a source or destination and must be chained to a connection (or other) stream.
File
- File對象代表文件或者目錄的路徑镊折,但不代表文件或者目錄本身
//創(chuàng)建代表已有文件的File對象
File f = new File("Mycode.txt");
//創(chuàng)建新的目錄
File dir = new File("MyDocuments");
dir.mkdir();
//列出目錄下的內容
if(dir.isDirectory()){
String[] dirContents = dir.list();}
//取得絕對路徑
System.out.println(dir.getAbsolutePath());
//刪除文件或目錄
boolean isDeleted = f.delete();
序列化(Serialization)
- 對象有狀態(tài)和行為兩種屬性猜极,行為存儲在類中,狀態(tài)存儲在每個個別的對象椭符,需要存儲對象狀態(tài)的時候使用序列化(Serialization)
//ObjectOutputStream與FileOutputStream都為OutputStream的子類,OutputStream為一個抽象類耻姥。
//左邊為對象字節(jié)流销钝,右邊為文件字節(jié)流,write向右琐簇,read向左
//characterOne必須是一個可被序列化的對象曙搬,需要實現Serializable接口才可以
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("MyGame.ser"));
oos.writeObject(characterOne);
oos.close();
當對象被序列化時,被該對象引用的實例化變量也被序列化鸽嫂,并且所有被引用的對象也都會被序列化
序列化版圖中如果有任何一個變量沒有序列化成功,則整個序列化都失敗征讲。例如序列化Pond對象時据某,如果Duck類沒有實現Serializable接口,則序列化失敗
如果某實例變量不能或不應該被序列化時诗箍,就把它標記為transient 癣籽,則序列化過程可以跳過這個實例變量。當序列化還原的時候,被transient的實例變量會以值為null的對象引用或0筷狼,false等默認primitive主數據類型返回
public class Pond{
public String name;
public Duck duck = new Duck();
}
public class Pond{
public String name;
public transient Duck duck = new Duck();
}
如果一個對象序列化后被還原瓶籽,且他的父類是不可序列化的,則父類的構造函數會跟著創(chuàng)建新的對象時一起執(zhí)行
如果兩個對象都有引用實例變量指向相同的對象埂材,那么他們在被序列化的時候只有一個引用對象會被存儲塑顺,另一個會復原成指向該引用
靜態(tài)變量不會被序列化,因為static代表每個類一個而不是每個變量一個俏险,所以對象被還原時严拒,靜態(tài)變量會維持類中原本的樣子,而不是存儲時的樣子
如果你的類可能在產生序列化對象之后繼續(xù)演變竖独,則會有與序列化時不同的serialVersionUID裤唠,那么在解序列化時則會失敗。所以如果你的類可能在產生序列化對象之后繼續(xù)演變莹痢,你可以手工獲得版本ID种蘸,然后將其拷貝到類上,但你必須確定你的改變不會對解序列化造成傷害
解序列化(Deserialization)
//ObjectInputStream與FileInputStream都為InputStream的子類竞膳,InputStream為一個抽象類航瞭。
//左邊為對象字節(jié)流,右邊為文件字節(jié)流顶猜,write向右沧奴,read向左
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("MyGame.ser"));
Object one = ois.readObject();
Object two = ois.readObject();
GameCharacter elf = (GameCharacter) one;
GameCharacter troll = (GameCharacter) two;
ois.close();
解序列化時Java虛擬機會嘗試尋找和加載對象的類,如果找不到或無法加載該類长窄,則會拋出異常滔吠。對于通過網絡傳送序列化對象來說,有一種機制可以讓類使用URL來指定自己的位置挠日,讓你可以把序列化對象當作參數的一部分來傳送疮绷,如果接受此調用的Java虛擬機沒有此類,則它可以自動使用URL來取回并加載該類
解序列化后新的對象會被配置在堆上嚣潜,但構造函數不會執(zhí)行冬骚,因為這樣會把對象的狀態(tài)抹去變成全新的狀態(tài)。如果對象在繼承樹上有個不可序列化的祖先類懂算,則該不可序列化類以及在它之上的類(就算可序列化也一樣)構造函數都會執(zhí)行只冻,且一經啟動,無法停止