1. 程式人生 > >Java序列化與static

Java序列化與static

簡介:

Java序列化,就是指將一個物件轉化為二進位制的byte流(注意,不是bit流),然後以檔案的方式進行儲存。

序列化操作:將物件儲存至檔案;

反序列化操作:從檔案恢復出物件;

配置:

物件如果要序列化,則必須整合Serializable介面;

在實現序列化時,用ObjectOutputStream實現;

而反序列化時,用ObjectInputStream實現;

方法:

1. 序列化:

(1) public ObjectOutputStream(OutputStream out) throws IOException

(2) public final void writeObject(Object obj)

(3) public void close() throws IOException

2.反序列化:

(1) public ObjectInputStream(InputStream in) throws IOException

(2) public final void readObject(Object obj)

(3) public void close() throws IOException

注意:

Java序列化是不能序列化static變數的,因為其儲存的是物件的狀態,而static變數儲存在全域性資料區,在物件未例項化時就已經生成,屬於類的狀態。

為了方便理解,我們舉例說明:

例子:

首先附上我們要序列化的物件的生成類:

package test;

import java.io.Serializable;

public class Person implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String name;
	private int age;
	
	public static String test="IBM";
	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;
	}
}
這裡我們有static變數test,賦值為IBM。

下面我們來看兩個程式碼:

package test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

public class Main{
	
	public static void main(String[] args){
		
		Person person = new Person();
		person.setAge(25);
		person.setName("YXY");
		Person.test="JAVA"; //modify the test value
		
		File file = new File("c:/test.txt");
		try {
			OutputStream out = new FileOutputStream(file);
			ObjectOutputStream objout = new ObjectOutputStream(out);
			objout.writeObject(person);
			objout.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		//code segment 1
		Person perobj = null;
		try {
			InputStream in = new FileInputStream(file);
			ObjectInputStream objin = new ObjectInputStream(in);
			perobj = (Person)objin.readObject();
			System.out.println(perobj.test);
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}
在這段程式碼裡,一開始我們就改了static變數test的值為JAVA,然後在code segment 1上面我們首先實現了序列化,接著我們在code segment 1下面實現了反序列化,讀取物件,執行,我們發現結果是JAVA,這時大家要問了,說不序列化static變數,怎麼讀取出來的反序列化物件的值,test的值還改變呢?這正是因為我們並沒有序列化static變數,所以它並沒有被寫入流中,所以當我們要讀取test的值時,它不可能在反序列化的檔案裡找到新的值,而是去全域性資料區取值,因為全域性資料區的值現在是JAVA,所以讀取出來的值就是改變後的值JAVA了。

下面我們再看一段程式碼:

package test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;

public class TEST {
	public static void main(String[] args){
		File file = new File("c:/test.txt");
		
		//code segment 1
		Person perobj = null;
		try {
			InputStream in = new FileInputStream(file);
			ObjectInputStream objin = new ObjectInputStream(in);
			perobj = (Person)objin.readObject();
			System.out.println(perobj.test);
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}
同樣也是反序列化操作,只不過放到了另一個檔案裡,這時再執行,結果就是IBM,不再是之前的JAVA,正是因為我們並沒有序列化static變數,所以test的值並不會改變,因為執行這個檔案時,全域性資料區裡的static變數也沒有改,所以它一如既往的是它的原始值IBM。

總結,綜上所述,Java序列化是不能序列化static變數的,大家在使用的時候一定不要混淆。