程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 關於Java對象序列化您不知道的5件事(1)

關於Java對象序列化您不知道的5件事(1)

編輯:關於JAVA

數年前,當和一個軟件團隊一起用 Java 語言編寫一個應用程序時,我體會到比一般程序員多知道一點關於 Java 對象序列化的知識所帶來的好處。

大約一年前,一個負責管理應用程序所有用戶設置的開發人員,決定將用戶設置存儲在一個 Hashtable 中,然後將這個 Hashtable 序列化到磁盤,以便持久化。當用戶更改設置時,便重新將 Hashtable 寫到磁盤。

這是一個優雅的、開放式的設置系統,但是,當團隊決定從 Hashtable 遷移到 Java Collections 庫中的 HashMap 時,這個系統便面臨崩潰。

Hashtable 和 HashMap 在磁盤上的格式是不相同、不兼容的。除非對每個持久化的用戶設置運行某種類型的數據轉換實用程序(極其龐大的任務),否則以後似乎只能一直用 Hashtable 作為應用程序的存儲格式。

團隊感到陷入僵局,但這只是因為他們不知道關於 Java 序列化的一個重要事實:Java 序列化允許隨著時間的推移而改變類型。當我向他們展示如何自動進行序列化替換後,他們終於按計劃完成了向 HashMap 的轉變。

本文是本系列的第一篇文章,這個系列專門揭示關於 Java 平台的一些有用的小知識 — 這些小知識不易理解,但對於解決 Java 編程挑戰遲早有用。

將 Java 對象序列化 API 作為開端是一個不錯的選擇,因為它從一開始就存在於 JDK 1.1 中。本文介紹的關於序列化的 5 件事情將說服您重新審視那些標准 Java API。

Java 序列化簡介

Java 對象序列化是 JDK 1.1 中引入的一組開創性特性之一,用於作為一種將 Java 對象的狀態轉換為字節數組,以便存儲或傳輸的機制,以後,仍可以將字節數組轉換回 Java 對象原有的狀態。

實際上,序列化的思想是 “凍結” 對象狀態,傳輸對象狀態(寫到磁盤、通過網絡傳輸等等),然後 “解凍” 狀態,重新獲得可用的 Java 對象。所有這些事情的發生有點像是魔術,這要歸功於 ObjectInputStream/ObjectOutputStream 類、完全保真的元數據以及程序員願意用 Serializable 標識接口標記他們的類,從而 “參與” 這個過程。

清單 1 顯示一個實現 Serializable 的 Person 類。

清單 1. Serializable Person

  1. package com.tedneward;
  2. public class Person
  3. implements Java.io.Serializable
  4. {
  5. public Person(String fn, String ln, int a)
  6. {
  7. this.firstName = fn; this.lastName = ln; this.age = a;
  8. }
  9. public String getFirstName() { return firstName; }
  10. public String getLastName() { return lastName; }
  11. public int getAge() { return age; }
  12. public Person getSpouse() { return spouse; }
  13. public void setFirstName(String value) { firstName = value; }
  14. public void setLastName(String value) { lastName = value; }
  15. public void setAge(int value) { age = value; }
  16. public void setSpouse(Person value) { spouse = value; }
  17. public String toString()
  18. {
  19. return "[Person: firstName=" + firstName +
  20. " lastName=" + lastName +
  21. " age=" + age +
  22. " spouse=" + spouse.getFirstName() +
  23. "]";
  24. }
  25. private String firstName;
  26. private String lastName;
  27. private int age;
  28. private Person spouse;

將 Person 序列化後,很容易將對象狀態寫到磁盤,然後重新讀出它,下面的 JUnit 4 單元測試對此做了演示。

清單 2. 對 Person 進行反序列化

  1. public class SerTest
  2. {
  3. @Test public void serializeToDisk()
  4. {
  5. try
  6. {
  7. com.tedneward.Person ted = new com.tedneward.Person("Ted", "Neward", 39);
  8. com.tedneward.Person charl = new com.tedneward.Person("Charlotte",
  9. "Neward", 38);
  10. ted.setSpouse(charl); charl.setSpouse(ted);
  11. FileOutputStream fos = new FileOutputStream("tempdata.ser");
  12. ObjectOutputStream oos = new ObjectOutputStream(fos);
  13. oos.writeObject(ted);
  14. oos.close();
  15. }
  16. catch (Exception ex)
  17. {
  18. fail("Exception thrown during test: " + ex.toString());
  19. }
  20. try
  21. {
  22. FileInputStream fis = new FileInputStream("tempdata.ser");
  23. ObjectInputStream ois = new ObjectInputStream(fis);
  24. com.tedneward.Person ted = (com.tedneward.Person) ois.readObject();
  25. ois.close();
  26. assertEquals(ted.getFirstName(), "Ted");
  27. assertEquals(ted.getSpouse().getFirstName(), "Charlotte");
  28. // Clean up the file
  29. new File("tempdata.ser").delete();
  30. }
  31. catch (Exception ex)
  32. {
  33. fail("Exception thrown during test: " + ex.toString());
  34. }
  35. }
  36. }
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved