Java序列化Serializable

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。

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章