如題
- 所有關(guān)聯(lián)的類需要繼承Serializable 接口
- 文件為空,直接反序列化為發(fā)生錯誤; 畢竟對象為null , 序列化到文件里不是空空的!
- 以下筆記的原文連接: https://www.cnblogs.com/fnz0/p/5410856.html
- 如果對象需要被寫出到文件上,那么對象所屬的類必須要實現(xiàn)Serializable接口。 Serializable接口沒有任何的方法,是一個標識接口而已。
- 對象的反序列化創(chuàng)建對象的時候并不會調(diào)用到構(gòu)造方法的、(這點文中沒有說到,想要驗證的同學(xué)在構(gòu)造方法后面加一句System.out.println("構(gòu)造方法執(zhí)行嗎?");,實際上構(gòu)造方法是不執(zhí)行的,自然這句話也沒有輸出了)
- serialVersionUID 是用于記錄class文件的版本信息的,serialVersionUID這個數(shù)字是通過一個類的類名、成員、包名、工程名算出的一個數(shù)字。
- 使用ObjectInputStream反序列化的時候,ObjeectInputStream會先讀取文件中的serialVersionUID,然后與本地的class文件的serialVersionUID
進行對比,如果這兩個id不一致,反序列則失敗。- 如果序列化與反序列化的時候可能會修改類的成員,那么最好一開始就給這個類指定一個serialVersionUID,如果一類已經(jīng)指定的serialVersionUID,然后
在序列化與反序列化的時候,jvm都不會再自己算這個 class的serialVersionUID了。- 如果一個對象某個數(shù)據(jù)不想被序列化到硬盤上,可以使用關(guān)鍵字transient修飾。
- 如果一個類維護了另外一個類的引用,則另外一個類也需要實現(xiàn)Serializable接口。
代碼
/**
* 對象輸出流
* @author Administrator
*
*/
// 必須實現(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) {
//對象輸出流,序列化到當前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, "機械"));
person.setBooks(books);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(path));
out.writeObject(person);
//在從當前目錄讀取, 輸出到控制臺;
//對象輸入流,反序列化到控制臺
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();
}
}
}
兩個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=機械]]]