Java克隆对象Object.clone

Object.clone方法可以帮助我们编写自己的类的克隆( clone )方法,用克隆方法将返回一个新的对象,其初始状态与调用clone方法的对象的当前状态相同,随后对这个新的克隆对象所做的修改应该不会对源对象的状态造成影响

默认的克隆(浅克隆)

package clonedemo;

public class CloneDemo implements Cloneable {
	private int x;
	public void setX(int x) {
		this.x = x;
	}
	public int getX() {
		return x;
	}
	@Override
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
	public static void main(String[] args) {
		CloneDemo src = new CloneDemo();
		src.setX(2);
		CloneDemo dic = null;
		try {
			dic = (CloneDemo) src.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(src.getClass().getName() + ":" + src.getX());
		System.out.println(dic.getClass().getName() + ":" + dic.getX());
	}
}

默认的克隆只是简单地将源对象中的每一个字段都赋值给目标对象中相同的字段,如果源对象有一个数组的引用,那么该对象的克隆体也将引用相同的字段,从而造成这个新的克隆对象所做的修改会对源对象的状态造成影响

package clonedemo;

public class CloneDemo implements Cloneable {
	private int[] x;
	public void setX(int[] x) {
		this.x = x;
	}
	public int[] getX() {
		return x;
	}
	@Override
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
	public static void main(String[] args) {
		CloneDemo src = new CloneDemo();
		int[] array={1,2,3};
		src.setX(array);  //源对象src的数组X设为1,2,3
		CloneDemo dic = null;
		try {
			dic = (CloneDemo) src.clone();   //克隆对象dic
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		array = dic.getX();  
		array[2] = 5;     //对克隆对象dic的数组X进行修改
		array = src.getX();   //查看源对象src中的数组X的状态
		for(int i:array){
			System.out.print(i+" ");  //造成对源对象状态的影响
		}
	}
}

正确的克隆(深克隆):覆盖clone方法,让它复制数组X的副本

package clonedemo;

public class CloneDemo implements Cloneable {
	private int[] x;
	public void setX(int[] x) {
		this.x = x;
	}
	public int[] getX() {
		return x;
	}
	@Override
	public Object clone() throws CloneNotSupportedException {
		CloneDemo obj =(CloneDemo) super.clone();
		obj.x = this.x.clone();
		return obj;
	}
	public static void main(String[] args) {
		CloneDemo src = new CloneDemo();
		int[] array={1,2,3};
		src.setX(array);  //源对象src的数组X设为1,2,3
		CloneDemo dic = null;
		try {
			dic = (CloneDemo) src.clone();   //克隆对象dic
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		array = dic.getX();  
		array[2] = 5;     //对克隆对象dic的数组X进行修改
		array = src.getX();   //查看源对象src中的数组X的状态
		for(int i:array){
			System.out.print(i+" ");  //造成对源对象状态的影响
		}
	}
}

禁止克隆,这样的类并不实现Cloneable接口,但是提供一个总能抛出CloneNotSupportedException异常的clone方法

package clonedemo;

public class NotClone implements Cloneable {
	public Object clone() throws CloneNotSupportedException{
		throw new CloneNotSupportedException("该对象无法进行克隆:"+this.getClass());
	}
	public static void main(String[] args){
		try {
			new NotClone().clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}


你可能感兴趣的:(Java克隆对象Object.clone)