1. 程式人生 > >Java物件序列化原理以及Serializable介面

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是不會被序列化的。