1.基本使用
提供一种持久化对象实例的机制,
Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient,transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。
package com.xiaoqiang.test;
import java.io.Serializable;
import java.util.Date;
public class XxqInfo implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1464964330763728461L;
private Date loggingDate = new Date();
private static String uid;
private transient String pwd;
XxqInfo(String user, String password) {
uid = user;
pwd = password;
}
public String toString() {
String password = null;
if (pwd == null) {
password = "NOT SET";
} else {
password = pwd;
}
return "logon info: \n " + "user: " + uid + "\n logging date : " + loggingDate.toString()
+ "\n password: " + password;
}
public Date getLoggingDate() {
return loggingDate;
}
public void setLoggingDate(Date loggingDate) {
this.loggingDate = loggingDate;
}
public static String getUid() {
return uid;
}
public static void setUid(String uid) {
XxqInfo.uid = uid;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
package com.xiaoqiang.test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class XxqInfoTest {
public static void main(String[] args) {
XxqInfo logInfo = new XxqInfo("123456", "132456");
System.out.println(logInfo.toString());
// 写操作
try {
ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("C://logInfo.out"));
o.writeObject(logInfo);
o.close();
} catch (Exception e) {// deal with exception}
}
// 读操作
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("C://logInfo.out"));
XxqInfo logInfo1 = (XxqInfo) in.readObject();
// logInfo1.setPwd("123456");
System.out.println(logInfo1.toString());
in.close();
} catch (Exception e1) {
e1.getStackTrace();
}
}
}
结果:
logon info:
user: 123456
logging date : Mon Jul 23 15:22:05 CST 2018
password: 132456
logon info:
user: 123456
logging date : Mon Jul 23 15:22:05 CST 2018
password: NOT SET
重点:为什么用trabsient
我们知道,当一个对象实现了Serilizable接口,这个对象就可以被序列化,我们不关心其内在的原理,只需要了解这个类实现了Serilizable接口,这个类的所有属性和方法都会自动序列化。而在开发过程中,我们可能要求:当对象被序列化时(写入字节序列到目标文件)时,有些属性需要序列化,而其他属性不需要被序列化,打个比方,如果一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字。
这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化。
所以,transient的用途在于:阻止实例中那些用此关键字声明的变量持久化;当对象被反序列化时(从源文件读取字节序列进行重构),这样的实例变量值不会被持久化和恢复。例如,当反序列化对象——数据流(例如,文件)可能不存在时,原因是你的对象中存在类型为java.io.InputStream的变量,序列化时这些变量引用的输入流无法被打开。
小结:
1,一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
2.transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
3.被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。
对于第三点,加上static之后,依然能把姓名输出。这是因为:反序列化后类中static型变量name的值为当前JVM中对应static变量的值,这个值是JVM中的不是反序列化得出的。下例可说明,其值时JVM中得到的而不是反序列化得到的:
参考资料: