檔案輸入和輸入出處理(六)-序列化和反序列化

化羽羽發表於2022-06-20

序列號

  • 序列號是序列化和反序列化的唯一標識,是一個長整型數值
  • 如果類中不自己定義序列號,系統會自動生成一個序列號
  • 當一方實體類發生改變,而呼叫方的序列號是不會跟著改變的,不知道物件已修改,會導致兩邊序列號不一致,反序列化失敗;
  • 所以要求必須手動生成一個序列號
  • 手動生成序列號後,可以解決目標類發生改變,不影響介面呼叫,物件可以正確序列化,不過物件修改的屬性返序列化後沒有值;

序列化物件類

//如果要支援序列化操作必須實現序列化介面
//賬戶類
public class Account implements Serializable {
	//手動生成序列號
    private static final long serialVersionUID = 2116137267832764072L;
    
    //賬戶名
    private  String aname;

    //賬戶密碼
    private String apwd;
    
    //set,get方法省略
    
    @Override
    public String toString() {
        return "Account{" +
                "aname='" + aname + '\'' +
                ", apwd='" + apwd + '\'' +
                '}';
    }
}    

序列化

使用ObjectOutputStream 類的 writeObject(Object obj)方法

//序列化物件,寫入檔案
public static void xlhAccount() throws IOException {
    Account account = new Account("KH96","12345");

    //使用物件輸出流,將記憶體中的物件寫入到檔案
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:/test/account.txt"));
    
    //直接寫入物件
    oos.writeObject(account);

    oos.close();
    System.out.println("序列化物件寫入成功");
}

序列化結果

反序列化

使用 ObjectInputStream 類的 readObject()方法

//反序列化目標物件讀取寫入序列化的檔案,進行反序列化,變為寫入的那個目標物件
public static void fxlhAccount() throws IOException, ClassNotFoundException {
    //使用物件輸入流,讀入寫入了序列化物件的檔案
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/test/account.txt"));
    
    Account account = (Account) ois.readObject();
    ois.close();
    
    //輸出目標物件
    System.out.println(account.toString());

    System.out.println("讀取序列化物件,反序列化成功");

}

反序列化結果

Account{aname='KH96', apwd='12345'}
讀取序列化物件,反序列化成功

當類發生改變

改變後的序列化物件

//賬戶類
public class Account implements Serializable {
	//手動生成序列號
    private static final long serialVersionUID = 2116137267832764072L;
    
    //賬戶名
    private  String aname;
    
    //賬戶密碼
    private String apwd;

    //新增手機
    private  String atel;
    
    //set,get方法省略
    
    @Override
    public String toString() {
        return "Account{" +
                "aname='" + aname + '\'' +
                ", apwd='" + apwd + '\'' +
                ", atel='" + atel + '\'' +
                '}';
    }
}

反序列化結果

Account{aname='KH96', apwd='12345', atel='null'}
讀取序列化物件,反序列化成功

如果沒有手動宣告序列號,實體類發生改變後就會java.io.InvalidClassException異常,序列號不一致而無法進行序列化。

相關文章