一.浅克隆概念与例子
1.1 浅克隆概念 clone是Object类的方法,为了避免我们创建的每个类都具有clone能力,clone方法在基础类中得到了保留,设为protected。这样 造成的后果就是:对于那些简单地使用一下这个类的客户程序员来说,他们不会默认地拥有这个方法。protected 只能显示地去调用。
PS:Java Obeject类解释文档:
/**
* Creates and returns a copy of this object. The precise meaning
* of "copy" may depend on the class of the object. The general
* intent is that, for any object {@code x}, the expression:
* <blockquote>
* <pre>
* x.clone() != x</pre></blockquote>
* will be true, and that the expression:
* <blockquote>
* <pre>
* x.clone().getClass() == x.getClass()</pre></blockquote>
* will be {@code true}, but these are not absolute requirements.
* While it is typically the case that:
* <blockquote>
* <pre>
* x.clone().equals(x)</pre></blockquote>
* will be {@code true}, this is not an absolute requirement.
Java Obeject类中clone的定义以及接口Cloneable的定义:
protected native Object clone() throws CloneNotSupportedException;
public interface Cloneable {}
1.2 浅克隆例子public class Prototype implements Cloneable{测试类:
private int a;
public Prototype(){}
public void setA(int a)
{
this.a = a;
}
public int getA()
{
return this.a;
}
public Object clone()
{
Object s = null;
try {
s = super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return s;
}
}
public class TestClone {
public static void main(String[] args) {
Prototype a = new Prototype();
Prototype b = (Prototype) a.clone();
//测试a,b对象中的值
System.out.println("a对象中的a值为:" + a.getA());
System.out.println("b对象中的a值为:" + b.getA());
//测试 x.clone() == x,证明a,b在内存中不同的位置
if(a.clone() == a) System.out.println("a.clone() == a --- true");
else System.out.println("a.clone() == a --- false");
//测试a.clone().equals(a)是否为true,证明内容是相同的
if(a.clone().equals(a)) System.out.println("a.clone().equals(a) --- true");
else System.out.println("a.clone().equals(a) --- false");
System.out.println("由==和equals都返回false,可以说明,clone后,对象地址不一样,对象内容的地址也不一样");
//测试x.clone().getClass() == x.getClass()是否为true
if(a.clone().getClass() == a.getClass())
System.out.println("x.clone().getClass() == x.getClass() --- true");
else
System.out.println("x.clone().getClass() == x.getClass() --- false");
System.out.println("所以说他们的原始对象为相同");
}
}
输出结果为:
a对象中的a值为:1
b对象中的a值为:1
a.clone() == a --- false
a.clone().equals(a) --- false
由==和equals都返回false,可以说明,clone后,对象地址不一样,对象内容的地址也不一样
x.clone().getClass() == x.getClass() --- true
所以说他们的原始对象为相同。
二.深度克隆概念与例子
个人理解就是类中有数组和对象这种情况。复制出来的只是复制了相同的地址,这样造成的后果通过一个变量改变这个对象会影响到另外的变量对应的这个对象。深度克隆相当于再把数组克隆一次,比如s.num =num.clone();具体代码如下:
public class Prototype implements Cloneable{
private char num[];
public Prototype()
{
num = new char[2];
}
public char[] getNum()
{
return num;
}
public void setNum(char num[])
{
this.num = num;
}
public Prototype clone()
{
Prototype s = null;
try {
s = (Prototype) super.clone();
s.num = num.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return s;
}
}
附上ArrayList中Java对Clone的使用
public Object clone() {
try {
@SuppressWarnings("unchecked")
ArrayList<E> v = (ArrayList<E>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}