Serializable接口初探
類通過實現 java.io.Serializable 接口以啟用其序列化功能。未實現此接口的類將無法使其任何狀態序列化或反序列化。可序列化類的所有子類型本身都是可序列化的。序列化接口沒有方法或字段,僅用于標識可序列化的語義。
Java的"對象序列化"能讓你將一個實現了Serializable接口的對象轉換成一組byte,這樣日后要用這個對象時候,你就能把這些byte數據恢復出來,并據此重新構建那個對象了。
要想序列化對象,你必須先創建一個OutputStream,然后把它嵌進ObjectOutputStream。這時,你就能用writeObject( )方法把對象寫入OutputStream了。
writeObject 方法負責寫入特定類的對象的狀態,以便相應的 readObject 方法可以還原它。通過調用 out.defaultWriteObject 可以調用保存 Object 的字段的默認機制。該方法本身不需要涉及屬于其超類或子類的狀態。狀態是通過使用 writeObject 方法或使用 DataOutput 支持的用于基本數據類型的方法將各個字段寫入 ObjectOutputStream 來保存的。
讀的時候,你得把InputStream嵌到ObjectInputStream里面,然后再調用readObject( )方法。不過這樣讀出來的,只是一個Object的reference,因此在用之前,還得先下傳。readObject 方法負責從流中讀取并還原類字段。它可以調用 in.defaultReadObject 來調用默認機制,以還原對象的非靜態和非瞬態字段。
? 最后結果如下:
??? node 0
? node 1
node 2
node 3
? node 4
node5
node 6
class?tree?implements?java.io.Serializable?{
????public?tree?left;
????public?tree?right;
????public?int?id;
????public?int?level;
????private?static?int?count?=?0;
????public?tree(int?depth)?{
????????id?=?count++;
????????level?=?depth;
????????if?(depth?>?0)?{
????????????left?=?new?tree(depth?-?1);
????????????right?=?new?tree(depth?-?1);
????????}
????}
????public?void?print(int?levels)?{
????????for?(int?i?=?0;?i?<?level;?i++)
????????????System.out.print("????");
????????System.out.println("?node??"?+?id);
????????if?(level?<=?levels?&&?left?!=?null)
????????????left.print(levels);
????????if?(level?<=?levels?&&?right?!=?null)
????????????right.print(levels);
????}
????public?static?void?main(String?argv[])?{
????????try?{
????????????/**?*//**//*?創建一個文件寫入序列化樹。?*/
????????????FileOutputStream?ostream?=?new?FileOutputStream("?tree.tmp?");
????????????/**?*//**//*?創建輸出流?*/
????????????ObjectOutputStream?p?=?new?ObjectOutputStream(ostream);
????????????/**?*//**//*?創建一個二層的樹。?*/
????????????tree?base?=?new?tree(2);
????????????p.writeObject(base);?//?將樹寫入流中。
????????????p.writeObject("?LiLy?is?惠止南國?");
????????????p.flush();
????????????ostream.close();?//?關閉文件。
????????????/**?*//**//*?打開文件并設置成從中讀取對象。?*/
????????????FileInputStream?istream?=?new?FileInputStream("?tree.tmp?");
????????????ObjectInputStream?q?=?new?ObjectInputStream(istream);
????????????/**?*//**//*?讀取樹對象,以及所有子樹?*/
????????????tree?new_tree?=?(tree)?q.readObject();
????????????new_tree.print(2);?//?打印出樹形結構的最上面?2級
????????????String?name?=?(String)?q.readObject();
????????????System.out.println("???"?+?name);
????????}?catch?(Exception?ex)?{
????????????ex.printStackTrace();
????????}
????}
}
可以看到,在序列化的時候,writeObject與readObject之間的先后順序。readObject將最先write的object read出來。用數據結構的術語來講就姑且稱之為先進先出吧!
在序列化時,有幾點要注意的:
1:當一個對象被序列化時,只保存對象的非靜態成員變量,不能保存任何的成員方法和靜態的成員變量。
????????2:如果一個對象的成員變量是一個對象,那么這個對象的數據成員也會被保存。
3:如果一個可序列化的對象包含對某個不可序列化的對象的引用,那么整個序列化操作將會失敗,并且會拋出一個NotSerializableException。我們可以將這個引用標記為transient,那么對象仍然可以序列化
還有我們對某個對象進行序列化時候,往往對整個對象全部序列化了,比如說類里有些數據比較敏感,不希望序列化,一個方法可以用transient來標識,另一個方法我們可以在類里重寫
private???void??readObject(java.io.ObjectInputStream?stream)??????throws??IOException,?ClassNotFoundException;
private???void??writeObject(java.io.ObjectOutputStream?stream)
??????throws??IOException這二個方法!
示例:
import?java.io.*;
class?ObjectSerialTest?{
????public?static?void?main(String[]?args)?throws?Exception?{
????????Employee?e1?=?new?Employee("?zhangsan?",?25,?3000.50);
????????Employee?e2?=?new?Employee("?lisi?",?24,?3200.40);
????????Employee?e3?=?new?Employee("?wangwu?",?27,?3800.55);
????????FileOutputStream?fos?=?new?FileOutputStream("?employee.txt?");
????????ObjectOutputStream?oos?=?new?ObjectOutputStream(fos);
????????oos.writeObject(e1);
????????oos.writeObject(e2);
????????oos.writeObject(e3);
????????oos.close();
????????FileInputStream?fis?=?new?FileInputStream("?employee.txt?");
????????ObjectInputStream?ois?=?new?ObjectInputStream(fis);
????????Employee?e;
????????for?(int?i?=?0;?i?<?3;?i++)?{
????????????e?=?(Employee)?ois.readObject();
????????????System.out.println(e.name?+?"?:?"?+?e.age?+?"?:?"?+?e.salary);
????????}
????}
}
class?Employee?implements?Serializable?{
????String?name;
????int?age;
????double?salary;
????transient?Thread?t?=?new?Thread();
????public?Employee(String?name,?int?age,?double?salary)?{
????????this.name?=?name;
????????this.age?=?age;
????????this.salary?=?salary;
????}
????private?void?writeObject(java.io.ObjectOutputStream?oos)?throws?IOException?{
????????oos.writeInt(age);
????????oos.writeUTF(name);
????????System.out.println("?Write?Object?");
????}
????private?void?readObject(java.io.ObjectInputStream?ois)?throws?IOException?{
????????age?=?ois.readInt();
????????name?=?ois.readUTF();
????????System.out.println("?Read?Object?");
????}
}
http://www.blogjava.net/supercrsky/articles/167111.html
轉載于:https://www.cnblogs.com/alionxd/articles/3099948.html
總結
以上是生活随笔為你收集整理的Serializable接口初探的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: int数组,找小于右边所有数,大于左边所
- 下一篇: 魔兽全屏改键工具