對(duì)象序列化:把一個(gè)對(duì)象轉(zhuǎn)換為01二進(jìn)制
對(duì)象反序列化:把一組01二進(jìn)制轉(zhuǎn)換為對(duì)象
ObjectOutputStream類可以實(shí)現(xiàn)對(duì)象序列化, 把對(duì)象轉(zhuǎn)換為01序列保存到文件中
ObejctInputStream類實(shí)現(xiàn)對(duì)象反序列化,從文件中讀取01序列轉(zhuǎn)換為對(duì)象
對(duì)象序列化/反序列化的前提是對(duì)象的類必須實(shí)現(xiàn)Serializable接口, 該接口是一個(gè)標(biāo)志接口,沒(méi)有任何方法,只是告訴編譯器這個(gè)類的對(duì)象可以序列化。
package com.wkcto.chapter06.objectstream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
/**
* 使用ObjectOutputStream可以實(shí)現(xiàn)對(duì)象的序列化, 把對(duì)象的01序列保存到文件中
*
* @author 蛙課網(wǎng)
*
*/
public class Test01 {
public static void main(String[] args) throws IOException {
//創(chuàng)建Person對(duì)象
Person lisi = new Person("lisi", 18);
//把lisi對(duì)象序列化, 就是把lisi對(duì)象保存到文件中
OutputStream out = new FileOutputStream("d:/obj.txt");
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(lisi); //對(duì)象序列化
oos.close();
}
}
package com.wkcto.chapter06.objectstream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
/**
* 使用ObjectInputStream類實(shí)現(xiàn)對(duì)象的反序列化,
* 就是從文件中把保存的對(duì)象讀取出來(lái)
*
* @author 蛙課網(wǎng)
*
*/
public class Test02 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
InputStream in = new FileInputStream("d:/obj.txt");
ObjectInputStream ois = new ObjectInputStream(in);
Object obj = ois.readObject(); //從文件中讀取一個(gè)對(duì)象, readObject()方法的返回值是Object類型的
//文件中實(shí)際存儲(chǔ)的是Person對(duì)象, 使用obj引用指向Person對(duì)象
System.out.println( obj ); //實(shí)際上調(diào)用的是Person對(duì)象的toString()方法
ois.close();
/*
* 在對(duì)象序列化之后 ,即把對(duì)象已經(jīng)保存到文件中了, 又在Person類中添加了一個(gè)字段,修改了Person類結(jié)構(gòu),
* 再進(jìn)行反序列化時(shí), 出現(xiàn)了異常:
* java.io.InvalidClassException:
* com.wkcto.chapter06.objectstream.Person; local class incompatible:
* stream classdesc serialVersionUID = 3479771803741762411,
* local class serialVersionUID = 1549311491347595402
* 分析原因:
* 流中類的描述信息中 serialVersionUID的值與本地字節(jié)碼文件中 serialVersionUID字段的值不相等引發(fā)的異常
*
* 當(dāng)類Person實(shí)現(xiàn)了Serializable接口后, 系統(tǒng)會(huì)自動(dòng)的在Person類中增加一個(gè)serialVersionUID序列化版本號(hào)字段
* 在lisi對(duì)象序列化時(shí), serialVersionUID字段的值是: 3479771803741762411
* 當(dāng)序列化后, 又在Person類添加了gender字段, 編譯后,在字節(jié)碼文件中重新生成了一個(gè)serialVersionUID的值:1549311491347595402
* 在進(jìn)行反序列化時(shí), 系統(tǒng)會(huì)檢查流中serialVersionUID序列化版本號(hào)字段與本地字節(jié)碼文件中serialVersionUID字段的值是否一樣
* 如果相等就認(rèn)為是同一個(gè)類的對(duì)象, 如果這個(gè)serialVersionUID序列化版本號(hào)字段的值不相等,就認(rèn)為是不同類的對(duì)象
* 解決方法:
* 保證反序列化時(shí)流中serialVersionUID字段 的值,與本地字節(jié)碼文件中serialVersionUID字段的值相等即可
* 可以在Person類實(shí)現(xiàn)了Serializable接口后, 手動(dòng)的添加一個(gè)serialVersionUID字段
*/
}
}
package com.wkcto.chapter06.objectstream;
import java.io.Serializable;
/**
* Person類的對(duì)象要想序列化, Person類必須實(shí)現(xiàn)Serializable接口
* Serializable接口是一個(gè)標(biāo)志接口,沒(méi)有任何方法
* @author 蛙課網(wǎng)
*
*/
public class Person implements Serializable{
String name;
int age;
String gender; //性別
//手動(dòng)的添加序列化版本號(hào)字段
private static final long serialVersionUID = -1345649873215667710L;
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", gender=" + gender + "]";
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
}