浅谈Java中transient关键字的作用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/li2327234939/article/details/76036085

一、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



猜你喜欢

转载自blog.csdn.net/li2327234939/article/details/76036085