transient字面意思是短暂的,转瞬即逝的,作为Java中的关键字,他的作用就是让其修饰的属性不被序列化。
序列化就是将对象转化为字节序列,序列化后的对象可以存入数据库、磁盘文件,也可用于网络传输(在Java中实现序列化的方法就是实现Serializable接口)。例如我们平时用的缓存,当我们需要持久化缓存的时候,都需要将存储的对象实现Serializable接口,目的就是为了让其可以序列化然后存入本地磁盘文件,读取时候会将本地磁盘文件存储的字节序列反序列化为我们存入的对象,从而实现持久化缓存的功能。
另外序列化还有几点需要注意
1、如果父类实现了序列化,那么子类默认自动实现序列化。
2、如果一个序列化对象引用了其他对象,那么序列化此对象的时候也会将引用对象序列化。
由上面的描述可以知道,transient可以让类的属性在序列化的时候忽略自己。那么为什么有些属性选择不序列化呢?原因有很多,比如说一些比较机密或敏感的信息,例如密码、卡号之类的,程序不希望他暴露在其他地方,所以选择序列化的时候将其排除在外。除此之外,比如有一些属性值是可以通过其他属性计算出来的,那就不需要额外再存一份了,这也可以节省一些磁盘空间。
通过Demo测试一下transient
public class Rectangle implements Serializable {
private Integer width;
private Integer height;
//由于面积可以通过长和宽计算出来,所以不选择序列化
private transient Integer area;
public Rectangle(Integer width, Integer height) {
this.width = width;
this.height = height;
this.area = width * height;
}
public void setArea() {
this.area = this.width * this.height;
}
@Override
public String toString() {
return "[width:"+width+";height:"+height+";area:"+area+"]";
}
}
public class TransientExample {
public static void main(String args[]) throws Exception {
Rectangle rectangle = new Rectangle(3,4);
System.out.println("1.原始对象\n"+rectangle);
ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("rectangle"));
// 往流写入对象
o.writeObject(rectangle);
o.close();
// 从流读取对象
ObjectInputStream in = new ObjectInputStream(new FileInputStream("rectangle"));
Rectangle rectangle1 = (Rectangle)in.readObject();
System.out.println("2.反序列化后的对象\n"+rectangle1);
rectangle1.setArea();
System.out.println("3.恢复成原始对象\n"+rectangle1);
in.close();
}
}
输出结果
使用transient须知
1、transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。
2、被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。
3、一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。也可以认为在将持久化的对象反序列化后,被transient修饰的变量将按照普通类成员变量一样被初始化。