serialVersionUID 對序列化,反序列化的影響

說一下個人理解,如果有不對的,希望大家多多指點啊!

如果一個類,實現了Serializable接口,則可以被序列化到本地。
此時,會有一個屬性,serialVersionUID,來表示該實體類的版本。

如果沒有指定serialVersionUID:
當一個類被序列化後,如果發生了改變,不包括增加空格,換行,增加註釋,等等,那麼反序列化後,會拋出異常:java.io.InvalidClassException。
這是因爲序列化的時候,如果沒有指定serialVersionUID,Java序列化機制會根據編譯的class(它通過類名,方法名等諸多因素經過計算而得,理論上是一一映射的關係,也就是唯一的)自動生成一個serialVersionUID作序列化版本比較用。
如果一個類發生修改,serialVersionUID則會發生改變。反序列的時候,JVM會把傳來的字節流中的serialVersionUID與相應實體(類)的serialVersionUID進行比較,如果相同就認爲是一致的,可以進行反序列化,否則就會出現序列化版本不一致的異常(InvalidClassException)。

如果指定了serialVersionUID:
如果序列化後,增加了屬性或者方法,則反序列化的時候,不會拋異常,但是新增加的屬性會被賦予對應類型的默認值,新增加的方法可以調用。
如果序列化後,刪除了屬性或者方法,則反序列化後,會忽略被刪除的屬性或方法。

具體實現的例子,參照的文章找不到原創作者,只能貼出參照時的地址:
http://blog.csdn.net/zzjjiandan/article/details/32336079
在此貼出格式化後的測試用代碼

測試用的實體類

package test;

import java.io.Serializable;

public class Serial implements Serializable {
    private static final long serialVersionUID = 1L;
    int id;
    String name;

    String test;
    public Serial(int id, String name,String test) {
        this.id = id;
        this.name = name;
        this.test = test;
    }
    public String toString() {
        return "DATA: " + id + " " + name + " " + test;
    }
    public void add(){
        System.out.println("add");
    }

    /*public Serial(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public String toString() {
        // return "DATA: " + id + " " + name + " " + test;
        return "DATA: " + id + " " + name;
    }*/
}

序列化的類

package test;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class SerialTest {
    public static void main(String args[]) {
        //Serial serial1 = new Serial(1, "song");
        Serial serial1 = new Serial(1, "song","aa");
        System.out.println("Object Serial" + serial1);
        try {
            FileOutputStream fos = new FileOutputStream("serialTest.txt");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(serial1);
            oos.flush();
            oos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

反序列化的類

package test;

import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class DeserialTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Serial serial2;
        try {
            FileInputStream fis = new FileInputStream("serialTest.txt");
            ObjectInputStream ois = new ObjectInputStream(fis);
            serial2 = (Serial) ois.readObject();
            ois.close();
            System.out.println("Object Deserial" + serial2);
            serial2.add();
        } catch (Exception e) { // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章