如果一个类没有继承Serilizable接口,那么它就不能被序列化,写入文件的时候会报异常。如果一个类继承了Serilizable接口,那么这个类的所有属性和方法都可以自动被序列化,而现实中我们又希望继承Serilizable的这个类的某些属性不被序列化保存该需要怎么做呢?这时就需要Transient修饰符上场了。总之,java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。
1 public class TransientTest { 2 3 public static void main(String args[]) throws FileNotFoundException, IOException, ClassNotFoundException{ 4 User user = new User("hoojjack", "123456"); 5 System.out.println("name="+user.getName()); 6 System.out.println("password="+user.getPassword()); 7 System.out.println("sex="+User.getSex()); 8 ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("C:\\Users\\joey\\Desktop\\user.txt")); 9 out.writeObject(user); 10 out.flush(); 11 out.close(); 12 User.setSex("girl"); 13 ObjectInputStream in = new ObjectInputStream(new FileInputStream("C:\\Users\\joey\\Desktop\\user.txt")); 14 User u=(User)in.readObject(); 15 in.close(); 16 System.out.println("After name="+u.getName()+" password="+u.getPassword()+" sex="+User.getSex()); 17 } 18 19 } 20 21 class User implements Serializable{ 22 private static final long serialVersionUID = 1L; 23 private String name; 24 private transient String password; 25 private static transient String sex="boy"; 26 //private static String sex="boy"; 27 28 public static String getSex() { 29 return sex; 30 } 31 32 33 public static void setSex(String sex) { 34 User.sex = sex; 35 } 36 37 38 public User(String name, String password) { 39 this.name = name; 40 this.password = password; 41 } 42 43 44 public String getName() { 45 return name; 46 } 47 48 public void setName(String name) { 49 this.name = name; 50 } 51 52 public String getPassword() { 53 return password; 54 } 55 56 public void setPassword(String password) { 57 this.password = password; 58 } 59 } 结果如下:
1 name=hoojjack 2 password=123456 3 sex=boy 4 After name=hoojjack password=null sex=girl
1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
2)transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
3)被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。如上面代码上的sex属性,即使加不加Transient修饰,结果都是一样的。
transient使用细节——被transient关键字修饰的变量真的不能被序列化吗?
在Exteralizable类中完全不一样,不管类继承了Serilizable还是被transient修饰的属性,如果没有显示的在exteralWrite中被写入,都不能序列化,请看下面代码:
1 public class ExternalizableTest implements Externalizable { 2 3 private transient String name; 4 private String sex; 5 6 public String getSex() { 7 return sex; 8 } 9 10 public void setSex(String sex) { 11 this.sex = sex; 12 } 13 14 public String getName() { 15 return name; 16 } 17 18 public void setName(String name) { 19 this.name = name; 20 } 21 22 public void writeExternal(ObjectOutput out) throws IOException { 23 out.writeObject(name); 24 //out.writeObject(sex); 25 26 } 27 28 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { 29 name = (String)in.readObject(); 30 // sex = (String) in.readObject(); 31 32 } 33 34 public static void main(String args[]) throws FileNotFoundException, IOException, ClassNotFoundException{ 35 ExternalizableTest test = new ExternalizableTest(); 36 test.setName("hoojjack"); 37 test.setSex("boy"); 38 ObjectOutput o = new ObjectOutputStream(new FileOutputStream("C:\\Users\\joey\\Desktop\\user.txt")); 39 o.writeObject(test); 40 ObjectInput in = new ObjectInputStream(new FileInputStream("C:\\Users\\joey\\Desktop\\user.txt")); 41 ExternalizableTest context = (ExternalizableTest)in.readObject(); 42 System.out.println("name="+context.getName()+" sex="+context.getSex()); 43 44 } 45 46 }
输出结果:
1 name=hoojjack sex=null
我们知道在Java中,对象的序列化可以通过实现两种接口来实现,若实现的是Serializable接口,则所有的序列化将会自动进行,若实现的是Externalizable接口,则没有任何东西可以自动序列化,需要在writeExternal方法中进行手工指定所要序列化的变量,这与是否被transient修饰无关。因此第二个例子输出的是变量content初始化的内容,而不是null。
Reference:
[1] http://www.cnblogs.com/lanxuezaipiao/p/3369962.html