序列化在java中是一个很重要的机制,一般来说,当我们创建一个对象之后,只要不终止程序,这个对象会一直存在。但是如果,我们需要在程序终止又重新启动之后,想要继续获取刚才所说对象对象的信息,就不得不依赖序列化机制。
(参考Thinking in Java. pageId:572)
1、
Java的对象序列化将那些实现了Serializable接口的对象转换成一个字节序列,并能够在以后将这个字节序列完全恢复为原来的对象,甚至于通过网络进行。
对象序列化的2个主要特性是:(1)Java的远程方法调用:将对象序列化之后,可以将本机的消息发送出去,在远程使用这个对象时就像在本机使用一样; (2)JavaBeans的配置信息所必需:使用一个Bean时,一般在设计阶段对其状态信息进行配置,而保存这个状态信息,并在程序启动时进行后期修复,依赖于对象序列化。
2、
由此可见序列化的重要性,但是是否所有的信息进行序列化都是可用的呢?当然不是!比如一个实现了序列化接口的登录类Logon,根据序列化特性,我们就可以通过网络获取对象,并且恢复其信息,显然密码字段绝对不允许这样。为了解决这个问题,可以引入transient这个关键字了。
transient:瞬时关键字,可以使某个特定子对象不想让java的序列化机制自动保存与恢复。
3、
下面通过一个例子看看效果:
package javaio.serializable;
import java.io.*;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
* @author wangjie
* @version 2018/11/20
* 通过登录信息序列化,演示transient关键字的作用
*/
public class Logon implements Serializable {
private Date date = new Date();
private String userName;
private transient String password;
public Logon(String userName,String password){
this.userName = userName;
this.password = password;
}
public String toString(){
return "logon info:\n userName:" +userName +
"\n date:" +date + "\n password: " +password;
}
public static void main(String[] args)throws Exception {
Logon a = new Logon("wangjie","wangjie123456");
System.out.println("logon a ="+a);
//序列化到文件
ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("Logon.out"));
//将对象a的信息写入文件
o.writeObject(a);
o.close();
//休眠1秒
TimeUnit.SECONDS.sleep(1);
//获取信息
ObjectInputStream in = new ObjectInputStream(new FileInputStream("Logon.out"));
System.out.println("当前时间: "+ new Date());
a=(Logon)in.readObject();
System.out.println("logon a="+a);
}
}
运行结果:
4、
可以看到,虽然Logon类实现了序列化接口,但是其中密码字段被transient关键字修饰后,序列化便不能将password敏感信息序列化。
而且看到:读取对象的时候,date信息仍然是序列化是的时间,并不是当前时间。
*************************************************************************
熟能生巧!
*************************************************************************