物件的序列化(Serialization)
from:http://www.cnblogs.com/vicenteforever/articles/1471775.html
一、序列化的概念和目的
1.什麼是序列化
物件的壽命通常隨著生成該物件的程式的終止而終止。有時候,可能需要將物件的狀態儲存下來,在需要時再將物件恢復。我們把物件的這種能記錄自己的狀態以便將來再生的能力。叫作物件的持續性(persistence)。物件通過寫出描述自己狀態的數值來記錄自己 ,這個過程叫物件的序列化(Serialization) 。序列化的主要任務是寫出物件例項變數的數值。如果交量是另一物件的引用,則引用的物件也要序列化。這個過程是遞迴的,序列化可能要涉及一個複雜樹結構的單行化,包括原有物件、物件的物件、物件的物件的物件等等。物件所有權的層次結構稱為圖表(graph)。
2.序列化的目的
Java物件的單行化的目標是為Java的執行環境提供一組特性,如下所示:
1) 儘量保持物件序列化的簡單扼要 ,但要提供一種途徑使其可根據開發者的要求進行擴充套件或定製。
2) 序列化機制應嚴格遵守Java的物件模型 。物件的序列化狀態中應該存有所有的關於種類的安全特性的資訊。
3) 物件的序列化機制應支援Java的物件持續性。
4) 物件的序列化機制應有足夠的 可擴充套件能力以支援物件的遠端方法呼叫(RMI)。
5) 物件序列化應允許物件定義自身 的格式即其自身的資料流表示形式,可外部化介面來完成這項功能。
二、序列化方法
從JDK1.1開始,Java語言提供了物件序列化機制 ,在java.io包中,介面Serialization用來作為實現物件序列化的工具 ,只有實現了Serialization的類的物件才可以被序列化。
Serializable介面中沒有任何的方法。當一個類宣告要實現Serializable介面時,只是表明該類參加序列化協議,而不需要實現任何特殊的方法。下面我們通過例項介紹如何對物件進行序列化。
1.定義一個可序列化物件
一個類,如果要使其物件可以被序列化,必須實現Serializable介面。我們定義一個類Student如下:
- import java.io.Serializable;
- public class Student implements Serializable {
- int id;// 學號
- String name;// 姓名
- int age;// 年齡
- String department; // 系別
- public Student(int id, String name, int age, String department) {
- this.id = id;
- this.name = name;
- this.age = age;
- this.department = department;
- }
- }
2.構造物件的輸入/輸出流
要序列化一個物件,必須與一定的物件輸出/輸入流聯絡起來,通過物件輸出流將物件狀態儲存下來,再通過物件輸入流將物件狀態恢復。
java.io包中,提供了ObjectInputStream和ObjectOutputStream將資料流功能擴充套件至可讀寫物件 。在ObjectInputStream 中用readObject()方法可以直接讀取一個物件,ObjectOutputStream中用writeObject()方法可以直接將物件儲存到輸出流中。
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- public class ObjectSer {
- public static void main(String args[]) throws IOException,
- ClassNotFoundException {
- Student stu = new Student(981036, "LiuMing", 18, "CSD");
- FileOutputStream fo = new FileOutputStream("data.ser");
- ObjectOutputStream so = new ObjectOutputStream(fo);
- try {
- so.writeObject(stu);
- so.close();
- } catch (IOException e) {
- System.out.println(e);
- }
- stu = null;
- FileInputStream fi = new FileInputStream("data.ser");
- ObjectInputStream si = new ObjectInputStream(fi);
- try {
- stu = (Student) si.readObject();
- si.close();
- } catch (IOException e)
- {
- System.out.println(e);
- }
- System.out.println("Student Info:");
- System.out.println("ID:" + stu.id);
- System.out.println("Name:" + stu.name);
- System.out.println("Age:" + stu.age);
- System.out.println("Dep:" + stu.department);
- }
- }
執行結果如下:
Student Info:
ID:981036
Name:LiuMing
Age:18
Dep:CSD
在這個例子中,我們首先定義了一個類Student,實現了Serializable介面 ,然後通過物件輸出流的writeObject()方法將Student物件儲存到檔案 data.ser中 。之後,通過對家輸入流的readObjcet()方法從檔案data.ser中讀出儲存下來的Student物件 。從執行結果可以看到,通過序列化機制,可以正確地儲存和恢復物件的狀態。
三、序列化的注意事項
1.序列化能儲存的元素
序列化只能儲存物件的非靜態成員交量,不能儲存任何的成員方法和靜態的成員變數,而且序列化儲存的只是變數的值,對於變數的任何修飾符都不能儲存。
2.transient關鍵字
對於某些型別的物件,其狀態是瞬時的,這樣的物件是無法儲存其狀態的。例如一個Thread物件或一個FileInputStream物件 ,對於這些欄位,我們必須用transient關鍵字標明,否則編譯器將報措。
另外 ,序列化可能涉及將物件存放到 磁碟上或在網路上發達資料,這時候就會產生安全問題。因為資料位於Java執行環境之外,不在Java安全機制的控制之中。對於這些需要保密的欄位,不應儲存在永久介質中 ,或者不應簡單地不加處理地儲存下來 ,為了保證安全性。應該在這些欄位前加上transient關鍵字。
下面是java規範中對transient關鍵字的解釋:
The transient marker is not fully specified by The Java Language Specification but is used in object serialization to mark member variables that should not be serialized.
以下是transient的一個應用舉例:
//LoggingInfo.java
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
public class LoggingInfo implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private Date loggingDate = new Date();
private String uid;
private transient String pwd;
LoggingInfo(String user, String password) {
uid = user;
pwd = password;
}
public String toString() {
String password = null;
if (pwd == null) {
password = "NOT SET";
} else {
password = pwd;
}
return "logon info: \n " + "user: " + uid + "\n logging date : "
+ loggingDate.toString() + "\n password: " + password;
}
public static void main(String[] args) {
LoggingInfo logInfo = new LoggingInfo("MIKE", "MECHANICS");
System.out.println(logInfo.toString());
try {
ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream(
"logInfo.out"));
o.writeObject(logInfo);
o.close();
} catch (Exception e) {// deal with exception
}
// To read the object back, we can write
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream(
"logInfo.out"));
LoggingInfo logInfo1 = (LoggingInfo) in.readObject();
System.out.println(logInfo1.toString());
} catch (Exception e) {// deal with exception
}
}
}
相關文章
- [.net 物件導向程式設計進階] (12) 序列化(Serialization)(四) 快速掌握JSON的序列化和反序列化物件程式設計JSON
- [.net 物件導向程式設計進階] (9) 序列化(Serialization) (一) 二進位制流序列化物件程式設計
- java安全編碼指南之:序列化SerializationJava
- [.net 物件導向程式設計進階] (10) 序列化(Serialization)(二) 通過序列化部落格園文章學習XML的序列化物件程式設計XML
- [.net 物件導向程式設計進階] (11) 序列化(Serialization)(三) 通過介面 IXmlSerializable 實現XML序列化 及 通用XML類物件程式設計XML
- 物件序列化(序列化)物件
- [.net 物件導向程式設計進階] (13) 序列化(Serialization)(五) Json 序列化利器 Newtonsoft.Json 及 通用Json類物件程式設計JSON
- .NET物件的XML序列化和反序列化物件XML
- 物件(List<T>)的序列化和反序列化物件
- JavaScript 物件序列化JavaScript物件
- java物件序列化Java物件
- Java物件的序列化和反序列化實踐Java物件
- C#中物件的序列化與反序列化C#物件
- JSON 物件序列化、反序列化JSON物件
- 談談 JAVA 的物件序列化Java物件
- C#中的物件序列化C#物件
- Java物件的序列化與反序列化-Json篇Java物件JSON
- 理解Java物件序列化Java物件
- Python中物件序列化和反序列化Python物件
- java 物件序列化要序列化那些內容Java物件
- C# 實現複雜物件的序列化與反序列化C#物件
- Java物件流與序列化Java物件
- 序列化物件(.NET中) (轉)物件
- 為什麼Java需要物件的序列化Java物件
- jackson對Exception型別物件的序列化與反序列化Exception型別物件
- Java基礎22--物件序列化和反序列化Java物件
- JavaScript物件序列化為JSONJavaScript物件JSON
- 深入理解Java物件序列化Java物件
- 使用jackson序列化物件物件
- Tinking in Java ---Java的NIO和物件序列化Java物件
- pickle和cPickle:Python物件的序列化(下)Python物件
- pickle和cPickle:Python物件的序列化(上)Python物件
- Python模組學習:marshal 物件的序列化Python物件
- Java:對一個物件序列化和反序列化的簡單實現Java物件
- ArcObjects SDK開發 025 AO中物件的序列化和反序列化Object物件
- 用C++優雅的實現物件到檔案的序列化/反序列化C++物件
- Python模組學習 :pickle, cPickle 物件序列化/反序列化Python物件
- 一文帶你全面瞭解java物件的序列化和反序列化Java物件