java中浅拷贝和深拷贝的区别


所谓的浅克隆,顾名思义就是很表面的很表层的克隆,如果我们要克隆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());
	}
}

 浅拷贝结果(Address 和Employee 里面的注释不去掉)

克隆之前:

姓名: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方法,重新复制,两层拷贝




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值