1、數據在串流中移動
串流要兩兩連接纔好傳輸數據。一個表示連接(eg:FileOutputStream),一個要被調用方法(ObjectOutputStream)。
爲什麼使用兩個:面向對象,每個類只要做好一件事。
2、序列化會將對象版圖上的所有東西存儲起來,被對象實例變量引用的所有對象都會被序列化。
3、實現serializable接口序列化:沒有實現任何方法,聲明這類是可以被序列化的
4、序列化的文件不可直接讀取,是二進制流
//將序列化對象寫入文件
//沒有myFile.txt這個文件的話就會創建
//創建讀取文件的fileoutputstream對象
FileOutputStream filestream = new FileOutputStream("myFile.txt");
//創建os對象,將對象打成串流送到FileOutputStream中保存
ObjectOutputStream os = new ObjectOutputStream(filestream);
//寫入對象
os.writeObject(characterOne);
//關閉流
os.close();
5、要被序列化的對象,被該對象實例變量引用的所有對象都應該可以被序列化,否則會無法序列化該對象
6、對於不需要被序列化的被引用的對象,標記爲transient(瞬時)類型的,序列化的時候會跳過它。
transient的對象會以null保存,或者基本數據類型默認值。
class Test implements Serializable {
//currentId 不會被序列化
transient String currentId;
String name;
}
7、解序列化Deserialization
//文件不存在會拋出異常,文件輸入流知道如何鏈接文件
FileInputStream filestream = new FileInputStream("myFile.txt");
//os靠鏈接的文件流來讀取對象
ObjectInputStream os = new ObjectInputStream(filestream);
//每次從流裏面讀取一個對象,讀取順序與寫入順序相同,次數超過會拋出異常
Object one = os.readObject();
//轉換對象類型
CharacterGame elf = (CharacterGame)one;
//關閉流, FileInputStream會跟着關閉
os.close();
8、解序列化流程:
a.對象從stream讀出來
b.Java虛擬機通過存儲的信息判斷對象的class類型
c.Java虛擬機嘗試尋找和加載對象的類,找不到或無法加載會拋出例外
d.新對象被分配在堆上,構造方法不會執行,對象回到存儲時的狀態。如果執行構造方法,對象就變成新的了。
e.若對象繼承樹上有非序列化父類,則該父類和它之上的父類的構造函數就會執行。從第一個不可序列化的父類開始,全部都會重新初始狀態。
f.對象的實例變量會還原成序列化時點的狀態值。transient變量會變爲null,或者基本數據類型的默認值。
9、靜態變量不會被序列化,是 每個類一個。對象被還原時候,靜態變量會維持類中原本的樣子,不是存儲時的樣子。
10、通過序列化來存儲對象狀態
11、
public class MyClass {
public static void main(String[] args) {
saveData();
readData();
}
public static void saveData() {
TestBox one = new TestBox(1, "huahua");
TestBox two = new TestBox(2, "xiaoxiao");
TestBox three = new TestBox(3, "yuanyaun");
try {
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("test.txt"));
outputStream.writeObject(one);
outputStream.writeObject(two);
outputStream.writeObject(three);
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
one = null;
two = null;
three = null;
}
public static void readData() {
try {
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("test.txt"));
TestBox onetest = (TestBox) inputStream.readObject();
TestBox twotest = (TestBox) inputStream.readObject();
TestBox threetest = (TestBox) inputStream.readObject();
System.out.println("one's age:" + onetest.age);
System.out.println("two's age:" + twotest.age);
System.out.println("three's age:" + threetest.age);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class TestBox implements Serializable {
int age;
String name;
public TestBox(int age, String name) {
this.age = age;
this.name = name;
}
}
12、區別於Parcelable,parcelable是安卓特有的序列化方式,serializable是Java的序列化方式。
parcelable適用於內存中傳遞數據,不適合網絡和本地保存數據,因爲不能保證數據的連續性。
serializable序列化的時候會產生大量的臨時變量,引起頻繁gc。