所谓的浅克隆,顾名思义就是很表面的很表层的克隆,如果我们要克隆Administrator对象,只克隆他自身以及他包含的所有对象的引用地址。
而深克隆,就是非浅克隆。克隆除自身以外所有的对象,包括自身所包含的所有对象实例。至于深克隆的层次,由具体的需求决定,也有“N层克隆”一说。
但是,无论所有的基本(primitive)类型数据是浅克隆还是深克隆,都会进行原值克隆。毕竟他们都不是对象,不是存储在堆中。注意:基本数据类型并不包括他们对应的包装类。
public class Address implements Cloneable{ private String state; //表示员工所在的国家 private String province;//表示员工所在的省份 private String city; //表示员工所在的城市 public Address(String state, String province, String city) { super(); this.state = state; this.province = province; this.city = city; } public String getState() { return state; } public void setState(String state) { this.state = state; } public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } /*@Override protected Object clone() throws CloneNotSupportedException { Object o = super.clone(); return o; }*/ @Override public String toString() { return "Address [state=" + state + ", province=" + province + ", city=" + city + "]"; } }
//其实下面就是Cloneable的接口内容,空无一物,只是用来表示这个类可以clone而已 /* package java.lang; public interface Cloneable { } */ //下面是Object类的方法,clone来自于Object类 /*public class Object { private static native void registerNatives(); static { registerNatives(); } public final native Class<?> getClass(); public native int hashCode(); public boolean equals(Object obj) { return (this == obj); } protected native Object clone() throws CloneNotSupportedException; public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } public final native void notify(); public final native void notifyAll(); public final native void wait(long timeout) throws InterruptedException; public final void wait(long timeout, int nanos) throws InterruptedException { if (timeout < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (nanos < 0 || nanos > 999999) { throw new IllegalArgumentException( "nanosecond timeout value out of range"); } if (nanos >= 500000 || (nanos != 0 && timeout == 0)) { timeout++; } wait(timeout); } public final void wait() throws InterruptedException { wait(0); } protected void finalize() throws Throwable { } }*/ public class Employee implements Cloneable { private String name; //员工的姓名 private String age; //员工的年龄 Address address; //员工的地址 public Employee(String name, String age, Address address) { super(); this.name = name; this.age = age; this.address = address; } /* 1. 让该类实现java.lang.Cloneable接口; 2. 确认持有的对象是否实现java.lang.Cloneable接口并提供clone()方法; 3. 重写(override)Object类的clone()方法,并且在方法内部调用持有对象的clone()方法;*/ public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override protected Object clone() throws CloneNotSupportedException { Employee employee = null; employee = (Employee)super.clone(); //employee.address = (Address)employee.address.clone(); return employee; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("姓名:"+ name +" ,"); sb.append("年龄:"+ age +"\n"); sb.append("地址:"+ address); return sb.toString(); } }
import java.util.Date; /** * * @author guoxiaoming *我们发现当我们克隆之后(浅克隆),如果改变克隆之后对象的非引用值,那么克隆之前的对象不会发生改变,于是克隆非引用 *对象成功 *当我们改变克隆之后对象的引用值address的时候,原来对象里面的值也是跟着改变了,于是表明引用对象克隆不成功 */ public class Test { public static void main(String args[]) throws CloneNotSupportedException { System.out.println("克隆之前:\n"); Address address = new Address("中国","安徽","阜阳"); Employee employee1 = new Employee("guoxiaoming","21",address); System.out.println(employee1.toString()); Employee employee2 = (Employee)employee1.clone(); employee2.setAge("22"); employee2.setName("guoximing"); employee2.address.setCity("界首"); System.out.println("克隆之后employee1:"); System.out.println(employee1.toString()); System.out.println("克隆之后employee2:"); System.out.println(employee2.toString()); } }
克隆之前:
姓名:guoxiaoming ,年龄:21
地址:Address [state=中国, province=安徽, city=阜阳]
克隆之后employee1:
姓名:guoxiaoming ,年龄:21
地址:Address [state=中国, province=安徽, city=界首]
克隆之后employee2:
姓名:guoximing ,年龄:22
地址:Address [state=中国, province=安徽, city=界首]
深拷贝(打开注释)
克隆之前:
姓名:guoxiaoming ,年龄:21
地址:Address [state=中国, province=安徽, city=阜阳]
克隆之后employee1:
姓名:guoxiaoming ,年龄:21
地址:Address [state=中国, province=安徽, city=阜阳]
克隆之后employee2:
姓名:guoximing ,年龄:22
地址:Address [state=中国, province=安徽, city=界首]
实现引用对象的成功拷贝,我们需要将引用对象也继承clonable接口,实现clone方法
然后在admin对象当中国的clone方法我们调用引用对象的clone方法,重新复制,两层拷贝