参考博客:Java transient关键字
“Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。”
为了验证这个问题,我们写代码:设置一个普通属性,一个transient标记的属性,然后将对象串行化后再读出来,发现transient标记的属性并没有被串行化。
1 public class MyTransient implements java.io.Serializable { 2 /** 3 * 4 */ 5 private static final long serialVersionUID = -8771981914596808776L; 6 private Date loggingDate = new Date(); 7 private String uid; 8 private transient String pwd; 9 10 public MyTransient(String user, String password) { 11 uid = user; 12 pwd = password; 13 } 14 15 public String toString() { 16 String password = null; 17 if (pwd == null) { 18 password = "NOT SET"; 19 } else { 20 password = pwd; 21 } 22 return "logon info: \n " + "user: " + uid + "\n logging date : " + loggingDate.toString() 23 + "\n password: " + password; 24 } 25 26 public static void main(String[] args) { 27 MyTransient logInfo = new MyTransient("MIKE", "MECHANICS"); 28 System.out.println(logInfo.toString()); 29 try { 30 ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("logInfo.out")); 31 o.writeObject(logInfo); 32 o.close(); 33 ObjectInputStream in = new ObjectInputStream(new FileInputStream("logInfo.out")); 34 MyTransient logInfo1 = (MyTransient) in.readObject(); 35 System.out.println(logInfo1.toString()); 36 } catch (Exception e) { 37 } 38 }
文末作者提醒:粗心对待transient域可能引起的潜在问题。
1 public class GuestLoggingInfo implements java.io.Serializable { 2 private Date loggingDate = new Date(); 3 private String uid; 4 private transient String pwd; 5 6 GuestLoggingInfo() { 7 uid = "guest"; 8 pwd = "guest"; 9 } 10 11 public String toString() { 12 // same as above 13 } 14 }
现在,如果我们穿行化GuestLoggingInfo的一个实例,将它写入磁盘,并且再将它从磁盘中读出,我们仍然看到读回的对象打印password 为 "NOT SET"。当从磁盘中读出某个类的实例时,实际上并不会执行这个类的构造函数,而是载入了一个该类对象的持久化状态,并将这个状态赋值给该类的另一个对象。
http://www.blogjava.net/fhtdy2004/archive/2009/06/20/286112.html
时间: 2024-11-07 12:52:56