以某个对象为原型,克隆出新的对象。克隆出的新对象不会影响原型对象。
要实现克隆要实现Cloneable接口和clone()方法
注意:clone() 是Object类的本地方法(效率高)
Cloneable只是一个空接口,但是想要克隆,必须实现Cloneable接口
public interface Cloneable { }
栗子:
public class People implements Cloneable { private Date birthday; private String name; @Override protected People clone() throws CloneNotSupportedException { People p = (People) super.clone(); return p; } public People(Date d, String name){ birthday = d; this.name = name; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } } class Test{ public static void main(String[] args) throws CloneNotSupportedException { Date d = new Date(1234567897); People p1 = new People(d, "张三"); People p2 = p1.clone(); System.out.println(p1 == p2); //false 克隆出一个新的对象 System.out.println(p1.getBirthday()); System.out.println(p2.getBirthday()); // 两个值完全相同 } }
这种克隆属于浅克隆:
仅仅把原型对象的值全部克隆给新对象,包括原型对象的一些引用地址(克隆过后,新/原型对象的引用地址指向同一个地址)
深克隆:连同属性也一起克隆
@Override protected People clone() throws CloneNotSupportedException { People p = (People) super.clone(); p.birthday = (Date) this.birthday.clone(); return p; }
利用序列化和反序列化 实现深克隆:
class Test{ public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException { Date d = new Date(1234567897); People p1 = new People(d, "张三"); //序列化 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(p1); byte[] bytes = bos.toByteArray(); //这个字节数组里面有对象的状态和对象属性的值 oos.close(); bos.close(); //反序列化 ByteArrayInputStream bis = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bis); People p2 = (People) ois.readObject(); System.out.println(p1.getBirthday()); System.out.println(p2.getBirthday()); //修改原型对象的属性 p1.setBirthday(new Date(987654321)); System.out.println(p1.getBirthday()); System.out.println(p2.getBirthday()); } }
结果: