序列化机制有一种很有趣的用法:
可以方便的克隆对象,只要对应的类是可序列化的即可。
操作流程:
直接将对象序列化到输出流中,然后将其读回。这样产生的新对象是对现有对象的一个深拷贝(deep copy)。在此过程中,不需要将对象写出到文件中,因为可以用ByteArrayOutputStream将数据保存到字节数组中;
tips:
方法的确很灵巧,但通常会比显式地构建新对象并复制或克隆数据域的克隆方法慢得多。
package io.clone; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Date; import java.util.GregorianCalendar; /*2015-7-10*/ public class SerialCloneTest { public static void main(String[] args) throws CloneNotSupportedException { Employee harry = new Employee("Harry Hacker", 60000, 1987, 1, 20); Employee harryClone = (Employee) harry.clone(); System.out.println(harry.equals(harryClone)); harry.raiseSalary(20); System.out.println(harry); System.out.println(harryClone); } } class SerialCloneable implements Cloneable, Serializable { private static final long serialVersionUID = 2439604536150013106L; @Override protected Object clone() throws CloneNotSupportedException { try { ByteArrayOutputStream bout = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bout); out.writeObject(this); out.close(); ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); ObjectInputStream in = new ObjectInputStream(bin); Object ret = in.readObject(); in.close(); return ret; } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return super.clone(); } } class Employee extends SerialCloneable { private static final long serialVersionUID = -167978670073609475L; private String name; private double salary; private Date hireDay; public Employee(String name, double salary, int year, int month, int dayOfMonth) { super(); this.name = name; this.salary = salary; GregorianCalendar calendar = new GregorianCalendar(year, month - 1, dayOfMonth); this.hireDay = calendar.getTime(); } public String getName() { return name; } public double getSalary() { return salary; } public Date getHireDay() { return hireDay; } public void raiseSalary(double byPercent) { double raise = salary * byPercent / 100; salary += raise; } @Override public String toString() { return getClass().getName() + " [name=" + name + ", salary=" + salary + ", hireDay=" + hireDay + "]"; } }
Output:
false io.clone.Employee [name=Harry Hacker, salary=72000.0, hireDay=Tue Jan 20 00:00:00 CST 1987] io.clone.Employee [name=Harry Hacker, salary=60000.0, hireDay=Tue Jan 20 00:00:00 CST 1987]