天天看點

淺談Java中transient關鍵字的作用

一、transient作用一:繼承Serializable接口實作序列化,Serializable自動化完成序列

1、transient關鍵字隻能修飾變量,而不能修飾方法和類。注意,本地變量是不能被transient關鍵字修飾的。

2、被transient關鍵字修飾的變量不再能被序列化。

3、一旦變量被transient修飾,變量将不再是對象持久化的一部分,該變量内容在序列化後無法獲得通路。也可以認為在将持久化的對象反序列化後,被transient修飾的變量将按照普通類成員變量一樣被初始化。

Demo Test1:

package com.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * @author 作者 : 李
 * @data 建立時間 : 2017年7月24日 下午6:57:04
 * @version 版本 : 1.0
 * @function 功能 : tansient的功能驗證(繼承Serializable接口實作序列化,Serializable自動化完成序列,)
 */
public class TransientTest implements Serializable {

	
	private static final long serialVersionUID = 111111111L;
	private transient int aa = 1;  
	private static int bb = 2;
	private transient static int cc = 3;
	private int dd = 4;

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		TransientTest transientTest = new TransientTest();
		transientTest.aa = 11;
		transientTest.bb = 22;
		transientTest.cc = 33;
		transientTest.dd = 44;
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("D:\\serilb.txt")));
		oos.writeObject(transientTest);

		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("D:\\serilb.txt")));
		TransientTest inverseSeriObject = (TransientTest) ois.readObject();
		System.out.println("aa----> " + inverseSeriObject.aa);  //被transient修飾的變量反序列化後,變量值被系統賦予預設初始值0(對象指派為null)
		System.out.println("bb----> " + inverseSeriObject.bb);  //被static修飾的變量反序列化後,變量值被保留
		System.out.println("cc----> " + inverseSeriObject.cc);  //被transient和static修飾的變量反序列化後,變量值被保留
		System.out.println("dd----> " + inverseSeriObject.dd);  //被無修飾的變量反序列化後,變量值被保留

	}

}
           

輸出結果:

aa----> 0
bb----> 22
cc----> 33
dd----> 44
           

二、transient作用二:繼承Externalizable接口實作序列化,Externalizable自動化完成序列

  我們知道在Java中,對象的序列化可以通過實作兩種接口來實作,若操作的是一個Serializable對象,則所有的序列化将會自動進行,若操作的是 一個Externalizable對象,則沒有任何東西可以自動序列化,需要在writeExternal方法中進行手工指定所要序列化的變量,這與是否被transient修飾無關。是以第二個例子輸出的是變量在聲明時初始化的内容,而不是系統預設初始值0(或者對象指派為null)

Demo Test2

package com.test;

import java.io.Externalizable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

/**
* @author 作者 : 李
* @data 建立時間 : 2017年7月24日 下午7:43:08
* @version 版本 : 1.0
* @function 功能 : tansient的功能驗證(繼承Externalizable接口實作序列化,Externalizable手動完成序列化)
*/
public class TransientTest2 implements Externalizable{
	private static final long serialVersionUID = 2222222222L;
	private transient int aa = 1;  
	private static int bb = 2;
	private transient static int cc = 3;
	private int dd = 4;
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		TransientTest2 transientTest = new TransientTest2();
		transientTest.aa = 11;
		transientTest.bb = 22;
		transientTest.cc = 33;
		transientTest.dd = 44;
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("D:\\externalserilb.txt")));
		oos.writeObject(transientTest);

		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("D:\\externalserilb.txt")));
		TransientTest2 inverseSeriObject = (TransientTest2) ois.readObject();
		System.out.println("aa----> " + inverseSeriObject.aa);  //被transient修飾的變量反序列化後,序列的是聲明時賦予的初始,建立對象後的改變無效
		System.out.println("bb----> " + inverseSeriObject.bb);  //被static修飾的變量反序列化後,序列的是建立對象後的對變量改變後的值,改變有效
		System.out.println("cc----> " + inverseSeriObject.cc);  //被transient和static修飾的變量反序列化後,序列的是建立對象後的對變量改變後的值,改變有效
		System.out.println("dd----> " + inverseSeriObject.dd);  //被無修飾的變量反序列化後,序列的是聲明時賦予的初始,建立對象後的改變無效
	}

	@Override
	public void writeExternal(ObjectOutput out) throws IOException {
		// TODO Auto-generated method stub
		out.writeObject(aa);
		out.writeObject(bb);
		out.writeObject(cc);
		out.writeObject(dd);
	}

	@Override
	public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
		// TODO Auto-generated method stub
		int aa = (int)in.readObject();
		int bb = (int)in.readObject();
		int cc = (int)in.readObject();
		int dd = (int)in.readObject();
	}
}

           

輸出:

aa----> 1
bb----> 22
cc----> 33
dd----> 4