Serailizable,类经过实现此接口使类对象能够被序列化,如把某对象保存到本地磁盘上,而后再从磁盘还原成jvm里的对象,代码以下: java
public static void main(String[] args) throws Exception { ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("d:/out.dat" )); User u1 = new User("user1" , "123" ); //User must implement Serializable User u2 = new User("user2" , "456" ); out.writeObject(u1); out.writeObject(u2); out.close(); ObjectInputStream in = new ObjectInputStream(new FileInputStream("d:/out.dat" )); User u1_from_file = (User) in.readObject(); User u2_from_file = (User) in.readObject(); System. out.println(u1_from_file.getName()); //user1 System. out.println(u2_from_file.getName()); //user2 System. out.println(u1_from_file.getPassword()); //123 System. out.println(u2_from_file.getPassword()); //456 System. out.println(u1 == u1_from_file); //false System. out.println(u2 == u2_from_file); //false }transient,若是不但愿密码被序列化,能够在password上使用transient修饰,这样在对象序列化过程当中就会忽略password。再次运行上面的Test类会获得不同的结果:
System. out.println(u1_from_file.getName()); //user1 System. out.println(u2_from_file.getName()); //user2 System. out.println(u1_from_file.getPassword()); //null System. out.println(u2_from_file.getPassword()); //null System. out.println(u1 == u1_from_file); //false System. out.println(u2 == u2_from_file); //false除transient外,还有另一种干预序列化的方式,就是给类添加方法,readObject和writeOjbect。
假设咱们为了对password保密,不但愿这个字段以默认的方式被序列化,由于这样很不安全;而是以加密码的方式序列化(这里只是把密码反转了一下) 安全
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); String reversedPwd = (String) in.readObject(); password = StringUtils.reverse(reversedPwd); } private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeObject(StringUtils. reverse(password)); }除上面两种干预方式外,还有另一种方式,方法readResolve,此方法返回的对象,会被做为readOjbect的返回值(即便readObject方法定义并无返回任何对象,java真tmd)
Externalizable,Externalizable继承自Serializable。
实现Externalizable接口的类必须有默认构造方法。
Externalizable接口定义了两个方法,只要实现这两个方法,完成对象的读取,以下:
jvm
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { name = (String) in.readObject(); password = (String) in.readObject(); } public void writeExternal(ObjectOutput out) throws IOException { out.writeObject( name); out.writeObject( password); }相比Serializable,Externalizable序列化的速度更快,序列化以后的数据更小,但读和取都须要开发人员自行实现; Serializable开发相对简单,速度慢,序列化后的数据更大些。 这两种序列化方式都有一个特色,若是多个对象a的内部属性b同时指向同一个对象,即同时引用了另一个对象b。序列化->反序列化以后,这几个对象属性仍是会同时指向同一个对象b,不会反序列化出多个b对象。 可是,若是多个对象a是屡次被序列化的,在反序列后对象b会被反序列化屡次,即多个a对象的属性b是不同的。