1. transient的作用及使用方法
我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过程,只要这个类实现了Serilizable接口,这个类的所有属性和方法都会自动序列化。
然而在实际开发过程中,我们常常会遇到这样的问题,这个类的有些属性需要序列化,而其他属性不需要被序列化,打个比方,如果一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字。换句话说,这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化。
总之,java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。
示例code如下:
1 import java.io.FileInputStream; 2 import java.io.FileNotFoundException; 3 import java.io.FileOutputStream; 4 import java.io.IOException; 5 import java.io.ObjectInputStream; 6 import java.io.ObjectOutputStream; 7 import java.io.Serializable; 8 9 /** 10 * @description 使用transient关键字不序列化某个变量 11 * 注意读取的时候,读取数据的顺序一定要和存放数据的顺序保持一致 12 * 13 * @author Alexia 14 * @date 2013-10-15 15 */ 16 public class TransientTest { 17 18 public static void main(String[] args) { 19 20 User user = new User(); 21 user.setUsername("Alexia"); 22 user.setPasswd("123456"); 23 24 System.out.println("read before Serializable: "); 25 System.out.println("username: " + user.getUsername()); 26 System.err.println("password: " + user.getPasswd()); 27 28 try { 29 ObjectOutputStream os = new ObjectOutputStream( 30 new FileOutputStream("C:/user.txt")); 31 os.writeObject(user); // 将User对象写进文件 32 os.flush(); 33 os.close(); 34 } catch (FileNotFoundException e) { 35 e.printStackTrace(); 36 } catch (IOException e) { 37 e.printStackTrace(); 38 } 39 try { 40 ObjectInputStream is = new ObjectInputStream(new FileInputStream( 41 "C:/user.txt")); 42 user = (User) is.readObject(); // 从流中读取User的数据 43 is.close(); 44 45 System.out.println(" read after Serializable: "); 46 System.out.println("username: " + user.getUsername()); 47 System.err.println("password: " + user.getPasswd()); 48 49 } catch (FileNotFoundException e) { 50 e.printStackTrace(); 51 } catch (IOException e) { 52 e.printStackTrace(); 53 } catch (ClassNotFoundException e) { 54 e.printStackTrace(); 55 } 56 } 57 } 58 59 class User implements Serializable { 60 private static final long serialVersionUID = 8294180014912103005L; 61 62 private String username; 63 private transient String passwd; 64 65 public String getUsername() { 66 return username; 67 } 68 69 public void setUsername(String username) { 70 this.username = username; 71 } 72 73 public String getPasswd() { 74 return passwd; 75 } 76 77 public void setPasswd(String passwd) { 78 this.passwd = passwd; 79 } 80 81 }
输出结果为:
read before Serializable: username: Alexia password: 123456 read after Serializable: username: Alexia password: null
密码字段为null,说明反序列化时根本没有从文件中获取到信息。