java核心學習(十七) IO框架---對象序列化
一、使用對象流實現序列化。
先定義一個可序列化的對象
package com.shy.IO; import java.io.Serializable; public class Person implements Serializable{ public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; }public void setName(String name) { this.name = name; } private int age; private String name; public Person(String name , int age){ this.age = age; this.name = name; } }
然後將Persen類的實例使用對象流序列化
package com.shy.IO;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class WriteObject {
public static void main(String[] args) {
try (
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("object.txt"));
) {
Person person = new Person("yuyu", 22);
outputStream.writeObject(person);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
最後再反序列化
package com.shy.IO;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class ReadObject {
public static void main(String[] args) {
try (
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("object.txt"))
) {
Person person = (Person) inputStream.readObject();
System.out.println(person.getName()+"的年齡為"+person.getAge());
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally {
}
}
}
由上面代碼可以看出,反序列化時必須進行downcasting,而且反序列化機制度區的僅僅是java對象的數據,而且沒有使用對象構造器,這表明反序列化機制無需通過構造起來初始化java對象。
二、java對象序列化算法內容簡介
1、所有保存到磁盤中的對象都有一個序列化編號。
2、當程序試圖序列化一個對象時,程序會先檢查該對象是否被序列化過,只有該對象從未(在本次虛擬機中)被序列化過,系統才會將對象轉化為字節序列並輸出。
3、如果某個對象已經序列化過,程序將只是直接輸出一個序列化編號,而不是再次重新序列化該對象。
三、自定義序列化
對實現了Serializable接口的對象,可使用下列三種方式來自定義序列化與反序列化。
第一種方式,若在實例成員變量前面使用transient關鍵字修飾,可以指定java序列化時無需理會該實例變量;
第二種方式,在需要序列化的類中提供如下特殊簽名的方法,在這些方法中分別對java對象的成員變量用out.writeObject()方法進行存取
private void writeObject(java.io.ObjectOutputStream out)throws IOException; private void readObject(java.io.ObjectInputStream in)throws IOException,ClassNotFoundException; private void readObjectNoData()throws ObjectStreamException;
第三種方式,在序列化時將該對象替換成其他對象,此時應該為序列化提供如下方法,序列化機制會序列化該方法返回的對象。
private Object writeReplace() throws ObjectStreamException;
通過上面介紹,可以知道java序列化機制在將對象序列化寫入文件之前,先調用被序列化對象的writeObject方法,然後再調用writeReplace方法,相對應的,在從文件中讀取對象時的最後,會調用readObject方法,之後再調用readResolve方法,該方法和writeReplace方法很像,可以將源序列化對象轉換為另一個對象來返回,可以用來實現白虎幸福之整個對象。
四、另一種序列化機制,實現Externalizable接口
與serializable這種聲明式接口不同,Externalizable接口裏面定義了兩個方法writeExternal() and readExternal()兩個方法,這兩個方法除了名字與writeObject和readObject不同外其他都相同,用處就是強制自定義序列化。
五、序列化的範圍
對象的類名和實例變量都會被序列化,方法、類變量,transient變量都不會被序列化。
六、serialVersionUID
在定義序列化對象時最好手動定義序列化對象的版本,也就是在序列化對象中定義一個靜態成員變量,private static fianl long serialVersionUID = 512L;用於保證class文件改變之後還可以正確反序列化。
java核心學習(十七) IO框架---對象序列化