Java物件序列化原理以及Serializable介面
Java物件的序列化就是把一個物件變成二進位制的資料流的一中方法,通過物件的序列化可以方便的實現物件的傳輸和儲存。
原理是:物件------------->轉換----------------->將物件轉變為二進位制的資料
在物件序列化時,只有其屬性被序列化(每個物件都具備相同的方法,但是每個物件的屬性不一定相同,也就是說物件儲存的只有其屬性資訊)
那麼一個類的物件要被序列化,這該類就必須實現java.io.Serializable介面,其原始碼如下:
public interface Serializable {
}
可以發現此介面沒有定義任何的方法,此介面只是一個標識介面,表示一個類具備了別序列化的能力。
如果要完成物件的輸入或輸出,必須依賴物件的輸入流(ObjectInputStream)和 物件輸出流(ObjectOutputStream)。
1、使用物件輸出流輸出序列化物件的過程稱之為序列化。
2、使用物件輸入流讀入物件的過程稱之為反序列話。
程式-------------->ObjectOutputStream------------------->序列化物件<----------------------ObjectInputStream-----------------------------程式
序列化 反序列化
一、ObjectOutputStream物件輸出流
他是OutputStream位元組數出流的子類,主要有如下方法:
1、 public ObjectOutputStream(OutputStream out) throw IOException 構造方法 如傳入輸出流物件
2、 public final void writeObject(Object obj) throw IOException 輸出物件
其實現如下:
定義一個序列化類。
package andy.serializable.test; import java.io.Serializable; /** * @author Zhang,Tianyou version:2014-11-20 下午2:41:12 * * */ public class Student implements Serializable { /** * */ private static final long serialVersionUID = 6095384564471868081L; // 實現serializable是指成為序列化類 private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
將物件輸出到檔案d:tes.txt 檔案中:
package andy.serializable.test;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
/**
* @author Zhang,Tianyou
* version:2014-11-20 下午2:45:24
*
*
*/
public class ObjectOutputStreamTest {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
File file = new File("d:" + File.separator + "test.txt");
ObjectOutputStream oos = null;
OutputStream outputStream = new FileOutputStream(file);
oos = new ObjectOutputStream(outputStream);
oos.writeObject(new Student("小明", 23));
outputStream.close();
oos.close();
}
}
其二進位制資料結果如下如下:
二、ObjectInputStream物件輸入流
能夠將被序列化的物件反序列話。是InputStream的子類,例項化是必須接受一個InputStream輸入流物件。
其主要方法如下:
1、public ObjectInputStream(InputStream in) throw IOException 構造方法
2、public final Object readObject() throw IOException, ClassNotFoundException 讀取指定位置的物件
其實現如下:
package andy.serializable.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
/**
* @author Zhang,Tianyou version:2014-11-20 下午2:45:46
*
*
*/
public class ObjectInputStreamTest {
/**
* @param args
* @throws IOException
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws IOException,
ClassNotFoundException {
// TODO Auto-generated method stub
File file = new File("d:" + File.separator + "test.txt");
ObjectInputStream ois = null;
InputStream inputStream = new FileInputStream(file);
ois = new ObjectInputStream(inputStream);
Object obj = ois.readObject();
Student student = (Student) obj;
ois.close();
inputStream.close();
System.out.println("test內容: name:" + student.getName() + "age:"
+ student.getAge());
}
}
執行如下:
test內容: name小明age:23
三、也可以自定義序列化介面,可以指定自己希望序列化的內容,只需實現Externalizable介面。
四、Serializable介面實現的操作實際是將一個物件的全部屬性進行了序列化,當然也可以通過Externalizable介面實現部分屬性的序列化,但更簡便的方法是使用transient關鍵字宣告不需要序列化的介面。
例如:
private transient String name;
那麼name是不會被序列化的。