transient关键字

今天在看JDK的一些源码的时候,发现有一个关键字transient自己没怎么玩过。所以这里写此博客来整理下这个关键字的用法。


去万能的百度上找资料,百度百科上是这么说的:

Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。当一个对象被序列化的时候,transient型变量的值不包括在序列化的表示中,然而非transient型的变量是被包括进去的。

翻找资料的时候,有一篇不错的博客,原文地址:http://www.cnblogs.com/dolphin0520/p/3933551.html。感谢作者的无私分享。


首先我们先写一段代码来序列化和反序列化一个Java对象:
package test;


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


/**
 * @创建作者: LinkinPark
 * @创建时间: 2016年1月6日
 * 
 * @功能描述:序列化和反序列化一个对象
 */
public class Test7
{


	private static final String filePath = "/Users/LinkinPark/Desktop/linkin.txt";


	public static void main(String[] args)
	{
		User user = new User().setUserName("LinkinPark").setPassWord("Binger1214");


		// 序列化一个对象
		try (ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(filePath)))
		{
			os.writeObject(user);
			System.out.println(user.toString());
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}


		// 反序列化一个对象
		try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(filePath)))
		{
			User userByRead = (User) in.readObject();
			System.out.println(userByRead.toString());
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}


	}


}


class User implements Serializable
{
	private String userName;// 用户姓名
	private String passWord;// 密码


	public String getUserName()
	{
		return userName;
	}


	public User setUserName(String userName)
	{
		this.userName = userName;
		return this;
	}


	public String getPassWord()
	{
		return passWord;
	}


	public User setPassWord(String passWord)
	{
		this.passWord = passWord;
		return this;
	}


	@Override
	public String toString()
	{
		return "User [userName=" + userName + ", passWord=" + passWord + "]";
	}


}


OK,现在我们使用这个transient关键字来修饰User对象的密码属性,代码如下:

package test;


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


/**
 * @创建作者: LinkinPark
 * @创建时间: 2016年1月6日
 * 
 * @功能描述:transient关键字使用
 */
public class Test7
{


	private static final String filePath = "/Users/LinkinPark/Desktop/linkin.txt";


	public static void main(String[] args)
	{
		User user = new User().setUserName("LinkinPark").setPassWord("Binger1214");


		// 序列化一个对象
		try (ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(filePath)))
		{
			os.writeObject(user);
			System.out.println(user.toString());
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}


		// 反序列化一个对象
		try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(filePath)))
		{
			User userByRead = (User) in.readObject();
			System.out.println(userByRead.toString());
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}


	}


}


class User implements Serializable
{
	private String userName;// 用户姓名
	private transient String passWord;// 密码


	public String getUserName()
	{
		return userName;
	}


	public User setUserName(String userName)
	{
		this.userName = userName;
		return this;
	}


	public String getPassWord()
	{
		return passWord;
	}


	public User setPassWord(String passWord)
	{
		this.passWord = passWord;
		return this;
	}


	@Override
	public String toString()
	{
		return "User [userName=" + userName + ", passWord=" + passWord + "]";
	}


}

对比2次控制台的输出,我们发现java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。

再明显一点我们打开2次序列化后的linkin.txt文件,发现第2次明显的没有将密码这个字段序列化到文件中。



通过上面的实践,这里来总结下transient关键字的用法:
1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
2)transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
3)被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。关于这点就不做多的解释了,类变量属于类的属性,存在于JVM内存中的,不能被序列化。


原文地址:https://www.cnblogs.com/LinkinPark/p/5232900.html