如題
- 所有關(guān)聯(lián)的類需要繼承Serializable 接口
- 文件為空,直接反序列化為發(fā)生錯(cuò)誤; 畢竟對象為null , 序列化到文件里不是空空的!
- 以下筆記的原文連接: https://www.cnblogs.com/fnz0/p/5410856.html
- 如果對象需要被寫出到文件上,那么對象所屬的類必須要實(shí)現(xiàn)Serializable接口。 Serializable接口沒有任何的方法,是一個(gè)標(biāo)識接口而已。
- 對象的反序列化創(chuàng)建對象的時(shí)候并不會調(diào)用到構(gòu)造方法的、(這點(diǎn)文中沒有說到,想要驗(yàn)證的同學(xué)在構(gòu)造方法后面加一句System.out.println("構(gòu)造方法執(zhí)行嗎?");,實(shí)際上構(gòu)造方法是不執(zhí)行的,自然這句話也沒有輸出了)
- serialVersionUID 是用于記錄class文件的版本信息的,serialVersionUID這個(gè)數(shù)字是通過一個(gè)類的類名、成員、包名、工程名算出的一個(gè)數(shù)字。
- 使用ObjectInputStream反序列化的時(shí)候,ObjeectInputStream會先讀取文件中的serialVersionUID,然后與本地的class文件的serialVersionUID
進(jìn)行對比,如果這兩個(gè)id不一致,反序列則失敗。- 如果序列化與反序列化的時(shí)候可能會修改類的成員,那么最好一開始就給這個(gè)類指定一個(gè)serialVersionUID,如果一類已經(jīng)指定的serialVersionUID,然后
在序列化與反序列化的時(shí)候,jvm都不會再自己算這個(gè) class的serialVersionUID了。- 如果一個(gè)對象某個(gè)數(shù)據(jù)不想被序列化到硬盤上,可以使用關(guān)鍵字transient修飾。
- 如果一個(gè)類維護(hù)了另外一個(gè)類的引用,則另外一個(gè)類也需要實(shí)現(xiàn)Serializable接口。
代碼
/**
* 對象輸出流
* @author Administrator
*
*/
// 必須實(shí)現(xiàn)Serializable接口
public class Person implements Serializable {
// private static final long serialVersionUID = 1L;
private String name;
private Dog dog;
private List<Book> books;
// 省略getter / setter / toString() ....
/**
* main測試類
* @param args
*/
public static void main(String[] args) {
//對象輸出流,序列化到當(dāng)前path目錄
String path="src/com/szs/serialize/person-data.txt";
try {
Person person = new Person();
person.setDog(new Dog("阿發(fā)","12"));
List<Book> books = new ArrayList<Book>();
books.add(new Book("Java", 200, "清社"));
books.add(new Book("C#", 300, "機(jī)械"));
person.setBooks(books);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(path));
out.writeObject(person);
//在從當(dāng)前目錄讀取, 輸出到控制臺;
//對象輸入流,反序列化到控制臺
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));
Person person2 = (Person) ois.readObject();
System.out.println(person2);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
兩個(gè)Person里的屬性里的對象
class Dog implements Serializable {
private String name;
private String age;
public Dog(String name,String age) {
this.name=name;
this.age=age;
}
// 省略getter / setter / toString() ....
}
class Book implements Serializable {
private String name;
private Integer price;
private String author;
public Book(String name, Integer price, String author) {
super();
this.name = name;
this.price = price;
this.author = author;
}
/// 省略getter / setter / toString() ....
}
測試結(jié)果
文件里 (亂碼了)
?sr ?com.szs.serialize.Person*e?犵韽?? ?L ?bookst ?Ljava/util/List;L ?dogt ?Lcom/szs/serialize/Dog;L ?namet ?Ljava/lang/String;xpsr ?java.util.ArrayListx佉?櫱a?
?I ?sizexp ?w? ?sr ?com.szs.serialize.Book??榾7?? ?L ?authorq ~ ?L ?nameq ~ ?L ?pricet ?Ljava/lang/Integer;xpt ?娓呯ぞt ?Javasr ?java.lang.Integer?鉅亣8? ?I
?valuexr ?java.lang.Number啲??斷? xp 萻q ~ ?t ?鏈烘t ?C#sq ~ ?,xsr ?
com.szs.serialize.Dog?n磻;y冴? ?L ?ageq ~ ?L ?nameq ~ ?xpt ?12t ?闃垮彂p
控制臺
Person [name=null, dog=Dog [name=阿發(fā), age=12],
books=[Book [name=Java, price=200, author=清社], Book [name=C#, price=300, author=機(jī)械]]]