Java的clone()方法简介

来源:互联网 发布:windows lua 下载 编辑:程序博客网 时间:2024/05/29 16:56

由于使用指针容易出现错误,Java取消了指针,但Java语言的每个new语句总是得到一个指针引用;

Java处理基本数据类型(int、char、double等)是按值传递,即对输入参数的复制;对于其他类型则是按引用传递,即对象的一个引用,不仅是在方法调用是传递引用,即便是使用赋值符号“=”时也是引用,这样会造成改变复制对象会影响到原有对象,可是在很多情况下,要求创建一个具有相同状态的对象后,对其进行修改不能影响到原有对象的状态,此时便需要使用Java中的clone()方法;

Object是所有类的父类,其提供的clone()方法作用是返回一个Object对象的副本,它并不是引用,而是一个新的对象,抛出的异常为CloneNotSupportedException,使用clone()方法的步骤如下:

1.继承Cloneable接口,如果在没有实现 Cloneable 接口的实例上调用 Object 的 clone()方法,则会导致抛出 CloneNotSupportedException 异常,此接口并不包含clone 方法;

2.重写clone()方法,并在该方法中调用super.clone(),这个方法会直接或间接性的调用Object类的clone()方法;

3.将浅复制的引用指向原有对象新的克隆体。


示例代码如下:

public class TestClone implements Cloneable{
private int value=1;

public int getValue() {
return value;
}


public void setValue(int value) {
this.value = value;
}

public void changeValue() {
this.value = 2;
}
public Object clone(){
Object o=null;
try {
o=(TestClone)super.clone();
} catch (CloneNotSupportedException e) {}
return o;
}


public static void main(String[] args) {
TestClone tc1=new TestClone();
TestClone tc2=(TestClone)tc1.clone();
tc2.changeValue();
System.out.println(tc1.getValue()+","+tc2.getValue());
}


}


输出结果为1,2;如果不使用clone()方法,那么输出的结果将为2,2;
上述代码使用的value为基本类型int,如果类中包含对象时便需要使用深复制进行解决。实现的方法为在对象调用clone()方法后,还需对对象的所有非基本类型的变量也使用clone()方法完成深复制。
示例代码如下:
输出结果为2017,2016;如果不进行深复制,那么输出的结果将为2017,2017;
下面介绍一下浅复制与深复制:
浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。
换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
 
深复制:被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对
象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用
的对象都复制了一遍。 深复制的举例如下:


import java.util.Calendar;


public class TestClone02 implements Cloneable{
private Calendar cal = Calendar.getInstance();


public Calendar getCal() {
return cal;
}
public void setCal(Calendar cal) {
this.cal = cal;
}
public void changeCal() {
this.cal.set(2016, 1, 1);
}
public Object clone(){
TestClone02 o=null;
try {
o=(TestClone02)super.clone();
} catch (CloneNotSupportedException e) {}
//进行深复制
o.cal=(Calendar)this.getCal().clone();
return o;
}


public static void main(String[] args) {
TestClone02 tc1=new TestClone02();
TestClone02 tc2=(TestClone02)tc1.clone();
tc2.changeCal();
System.out.println(tc1.getCal().get(Calendar.YEAR)+","+tc2.getCal().get(Calendar.YEAR));
}


}


举例有一个类Demo定义如下:



class Demo{
public int i;
public StringBuffer sb;
}


如果对该类的对象进行复制,则浅复制与深复制的区别可表示为下图:


0 0