Serailizable,类通过实现此接口使类对象可以被序列化,如把某对象保存到本地磁盘上,然后再从磁盘还原成jvm里的对象,代码如下:
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接口定义了两个方法,只要实现这两个方法,完成对象的读取,如下:
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序列化的速度更快,序列化之后的数据更小,但读和取都需要开发人员自行实现;