transient(瞬时)关键字

当我们序列化进行控制时,可能存在某个特定子对象不想让 Java 的序列化机制自动保存与
恢复。如果子对象表示的是我们不想序列化的敏感信息(如密码),通常就会面临这种情况。
即使对象中的这些信息是“private”(私有)属性,一经序列化处理,人们就可以通过读取
文件,或者拦截网络传输的方式来访问到它。
有一种防止对象的敏感部分被序列化的办法,就是将我们自己的类实现为 Externalizable,
如前面所示。这样一来,没有任何东西可以自动序列化,并且我们可以在 writeExternal()
内部只对所需部分进行显式的序列化。
然而,如果我们正在操作的是一个 Serializable 对象,那么所有序列化操作都会自动进行。
为了能够予以控制,可以用 transient(瞬时)关键字逐个域地关闭序列化,它意旨“不用
麻烦你保存或恢复数据——我自己会处理的”。
例如,假设某个 Login 对象保存某个特定的登录会话信息。登录的合法性通过校验之后,
我们想把数据保存下来,但不包括密码。为做到这一点,最简单的办法是实现 Serializable,
并将 password 域标志为 transient。下面是具体的代码:


//: c12:Logon.java 
// Demonstrates the "transient" keyword.
// {Clean: Logon.out}
import java.io.*;
import java.util.*;


public class Logon implements Serializable {
    private Date date = new Date();
  private String username;
    private transient String password;
    public Logon(String name, String pwd) {
    username = name;
    password = pwd;
    } 
  public String toString() {
        String pwd = (password == null) ? "(n/a)" : password;
        return "logon info: \n     username: " + username +
      "\n   date: " + date + "\n   password: " + pwd;
    } 
    public static void main(String[] args) throws Exception {
        Logon a = new Logon("Hulk", "myLittlePony");
        System.out.println( "logon a = " + a);
        ObjectOutputStream o = new ObjectOutputStream(
      new FileOutputStream("Logon.out"));
    o.writeObject(a);
    o.close();
        Thread.sleep(1000); // Delay for 1 second
    // Now get them back:
    ObjectInputStream in = new ObjectInputStream(
      new FileInputStream("Logon.out"));
        System.out.println("Recovering object at "+new Date());
    a = (Logon)in.readObject();
        System.out.println("logon a = " + a);
    } 
} ///:~
我们可以看到,其中的 date 和 username 域是一般数据(不是 transient),所以它们会
被自动序列化。而 password 是 transient,所以不会被自动保存到磁盘;另外,自动序列
化机制也不会尝试去恢复它。输出如下:


logon a = logon info:
   username: Hulk
      date: Mon Oct 21 12:10:13 MDT 2002 
   password: myLittlePony
Recovering object at Mon Oct 21 12:10:14 MDT 2002 
logon a = logon info:
   username: Hulk
      date: Mon Oct 21 12:10:13 MDT 2002 
   password: (n/a)


当对象被恢复时,password 域就会变成 null。注意必须用 toString()检查 password 是
否为 null,因为如果用重载的“+”运算符来连接 String 对象,并且该运算符如果遇到一个
null 引用,我们就会得到 NullPointerException 异常(新版 Java 可能会包含避免这个问
题的代码)。


我们还可以发现:date 域被存储了到磁盘并从磁盘上被恢复了出来,而且没有再重新生成。
由于 Externalizable 对象在缺省情况下不保存它们的任何域,所以 transient 关键字只能

和 Serializable 对象一起使用。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值