学习java以来,没有特别的关注transient关键字,工作中也很少使用,但是今天在看公司项目代码中,其中使用到transient修饰方法,不理解,于是在网上查找资料之后,整理得此篇博文。
正文
java transient关键字作用:实现Serilizaable接口的类的对象可以被序列化,但是在实际开发过程中,某个实例变量不能或不应该被序列化,就把它标记为transient(瞬时)的,这样这个属性的生命周期仅存在于调用者的内存中而不会写到磁盘里持久化。
<span style="font-size:14px;">import java.io.Serializable;
public class Test04 implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
transient String currentID;
String userName;
......
}</span>
如果你无法序列化的变量不能被存储,可以使用transient这个关键字把它标记出来,序列化程序会跳过它。
- 一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问
- transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
- 被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。
为什么有些变量不能被序列化?
动态数据只可以在执行时求出而不能或不必存储,以及一些需要保密的数据(密码、银行卡号)不被序列化,为了安全,不希望在网络上操作中被传输。虽然java函数中大部分类似可以被序列化,但是还是无法将网络联机之类的东西保存下来。
<span style="font-size:14px;">public class TestTransient {
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
A a = new A(25, "张三");
System.out.println(a);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d://test.txt"));
oos.writeObject(a);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d://test.txt"));
a = (A) ois.readObject();
System.out.println(a);
}
}
class A implements Serializable {
int a;
transient String b;
public A(int a, String b) {
this.a = a;
this.b = b;
}
public String toString() {
return "a = " + a + ",b = " + b;
}
}</span>
运行结果:
a = 25,b = 张三
a = 25,b = null
public class ExternalizableTest implements Externalizable {
private transient String content = "我将会被序列化,不管我是否被transient关键字修饰";
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(content);
}
@Override
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
content = (String) in.readObject();
}
public static void main(String[] args) throws Exception {
ExternalizableTest et = new ExternalizableTest();
ObjectOutput out = new ObjectOutputStream(new FileOutputStream(
new File("test")));
out.writeObject(et);
ObjectInput in = new ObjectInputStream(new FileInputStream(new File(
"test")));
et = (ExternalizableTest) in.readObject();
System.out.println(et.content);
out.close();
in.close();
}
}
运行结果:
我将会被序列化,不管我是否被transient关键字修饰
被transient修饰变量,如果类实现的接口是Externalizable,则没有任何东西可以序列化,需要在writeExternal方法中进行手工指定所要序列化的变量,这与是否被transient修饰无关。