这里面涉及到两个类,一个是person类,一个是测试类test
首先我们说到的是浅克隆,对某个对象实施Clone时对其是一无所知的,它仅仅是简单地执行域对域的copy,如果是基本数据类型(int,float,char等)到没什么问题,基本遇上如string,Integer等不可变对象的时候也没有什么问题,但是如果遇上了date这个可变对象,或者是自己定义的可变对象,他只是简单的复制一下引用这些可变对象,而不是把这些可变对象再一次的复制
先上person类,这里面虽然是实现Cloneable接口,但是里面没有重写方法,只是super了一下就算了
package com.ray.object; import java.util.Date; /** * 人 * * @author ray * @since 2015-05-07 * @version 1.0 * */ public class Person implements Cloneable { private int id = 0; private String name = ""; private Date birthday = null; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Override protected Object clone() { Object obj = null; try { obj = super.clone(); } catch (CloneNotSupportedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return obj; } }
再上测试类
package com.ray.object; import java.util.Date; /** * 浅克隆和深克隆 * * @author ray * @since 2015-05-07 * @version 1.0 * */ public class Test { public static void main(String[] args) { Person bill = new Person(); bill.setId(1); bill.setName("bill"); bill.setBirthday(new Date()); System.out.println("bill.getId() --- "+bill.getId()); System.out.println("bill.getName() --- "+bill.getName()); System.out.println("bill.getBirthday() --- "+bill.getBirthday()); Person jack = (Person) bill.clone(); System.out.println("jack.getId() --- "+jack.getId()); System.out.println("jack.getName() --- "+jack.getName()); System.out.println("jack.getBirthday() --- "+jack.getBirthday()); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Date jacksBirthday = jack.getBirthday(); jacksBirthday.setTime(System.currentTimeMillis()); System.out.println("bill.getId() --- "+bill.getId()); System.out.println("bill.getName() --- "+bill.getName()); System.out.println("bill.getBirthday() --- "+bill.getBirthday()); System.out.println("jack.getId() --- "+jack.getId()); System.out.println("jack.getName() --- "+jack.getName()); System.out.println("jack.getBirthday() --- "+jack.getBirthday()); } }
输出:
bill.getId() --- 1
bill.getName() --- bill
bill.getBirthday() --- Thu May 07 08:56:33 CST 2015
jack.getId() --- 1
jack.getName() --- bill
jack.getBirthday() --- Thu May 07 08:56:33 CST 2015
bill.getId() --- 1
bill.getName() --- bill
bill.getBirthday() --- Thu May 07 08:56:35 CST 2015
jack.getId() --- 1
jack.getName() --- bill
jack.getBirthday() --- Thu May 07 08:56:35 CST 2015
由上面可以看见,基本jack这个对象是clone了bill这个对象,但是这里面只是简单复制一下引用,当我们修改jack对象里面的生日时,bill的生日竟然也跟着变了
下面,我们再说一下深克隆,就是把对象的所有域全部复制一份
先上Person类,这次Person类重写了clone方法,除了super之外,还把里面的birthday属性也复制一份
package com.ray.object; import java.util.Date; /** * 人 * * @author ray * @since 2015-05-07 * @version 1.0 * */ public class Person implements Cloneable { private int id = 0; private String name = ""; private Date birthday = null; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Override protected Object clone() { Object obj = null; try { obj = super.clone(); //下面把生日也复制一份 Person person = (Person) obj; person.birthday = (Date) birthday.clone(); } catch (CloneNotSupportedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return obj; } }
再上Test类,其实Test类没有做任何的改动,这里只是为了阅读方便,也写上了
package com.ray.object; import java.util.Date; /** * 浅克隆和深克隆 * * @author ray * @since 2015-05-07 * @version 1.0 * */ public class Test { public static void main(String[] args) { Person bill = new Person(); bill.setId(1); bill.setName("bill"); bill.setBirthday(new Date()); System.out.println("bill.getId() --- "+bill.getId()); System.out.println("bill.getName() --- "+bill.getName()); System.out.println("bill.getBirthday() --- "+bill.getBirthday()); Person jack = (Person) bill.clone(); System.out.println("jack.getId() --- "+jack.getId()); System.out.println("jack.getName() --- "+jack.getName()); System.out.println("jack.getBirthday() --- "+jack.getBirthday()); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Date jacksBirthday = jack.getBirthday(); jacksBirthday.setTime(System.currentTimeMillis()); System.out.println("bill.getId() --- "+bill.getId()); System.out.println("bill.getName() --- "+bill.getName()); System.out.println("bill.getBirthday() --- "+bill.getBirthday()); System.out.println("jack.getId() --- "+jack.getId()); System.out.println("jack.getName() --- "+jack.getName()); System.out.println("jack.getBirthday() --- "+jack.getBirthday()); } }
输出:
bill.getId() --- 1
bill.getName() --- bill
bill.getBirthday() --- Thu May 07 09:22:03 CST 2015
jack.getId() --- 1
jack.getName() --- bill
jack.getBirthday() --- Thu May 07 09:22:03 CST 2015
bill.getId() --- 1
bill.getName() --- bill
bill.getBirthday() --- Thu May 07 09:22:03 CST 2015
jack.getId() --- 1
jack.getName() --- bill
jack.getBirthday() --- Thu May 07 09:22:05 CST 2015
由上面的输出可以看到,jack里面birthday的改动不再影响bill里面的birthday
最后,我们来说一下使用=来copy对象,其实只是把对象的引用复制一份过去给另外的对象,对象是没有做出任何改变