您的位置:首页 > 编程语言 > Java开发

java 深拷贝

2016-01-05 00:00 435 查看
obj.clone().getClass()==obj.getClass(),即它们具有相同的类型。还有一点,因为只是简单的将对象的空间进行复 制,所以如果类具有引用类型的实例变量的话,也只是将这个引用进行拷贝,并不复制其引用的对象。这就导致拷贝对象的引用实例变量与原对象的指向相同的对 象,这就是传说中的“浅拷贝”。如果实例变量引用的对象是不可变的,类似于String,则拷贝对象与原对象不能互相影响,这样的拷贝是成功的。但是如果 引用的是可变对象,它们就会影响彼此,对于成功的拷贝而言,这是不允许的。可以对可变的实例变量对象进行特殊处理,以实现拷贝对象和原对象不能相互影响的 “深拷贝”。

由于Object.clone()方法是protected的,所以它只能在lang包中的类或是其子类的方法内部被调用,所以,如果像下面这样调用,会 编译出错,在Person kobe_bak=kobe.clone();报错,说clone只能在Object的protected作用域访问。

一个类可以被clone,必须满足两点:
第一,它必须实现了Cloneable接口,否则会抛出CloneNotSupportedException异常。
第二,它必须提供一个public的clone方法,也就是重写Object.clone()方法,否则编译不能通过。
第三,对于存在可变域的类,在clone方法中需要对这些可变域进行拷贝。

package test.javacopy;

import java.util.Date;

/**
* Created by Administrator on 2016/1/5.
*/
public class JavaCopy implements Cloneable {

private String name;
private int age;
private Date date;
private TestCopy testcopy;

public JavaCopy(String name,int age){
this.name = name;
this.age = age;
}

public JavaCopy clone(){
JavaCopy javaCopy = null;
try {
javaCopy = (JavaCopy)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return javaCopy;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public Date getDate() {
return date;
}

public void setDate(Date date) {
this.date = date;
}

public TestCopy getTestcopy() {
return testcopy;
}

public void setTestcopy(TestCopy testcopy) {
this.testcopy = testcopy;
}
}

package test.javacopy;

import java.io.Serializable;
import java.util.Date;

/**
* Created by Administrator on 2016/1/5.
*/
public class TestCopy implements Serializable,Cloneable{

private String name;
private String age;

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;
}

public TestCopy clone(){
TestCopy testCopy = null;
try {
testCopy = (TestCopy)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return testCopy;
}

public static void main(String args[]) {
TestCopy testcopy = new TestCopy();
testcopy.setName("javaCopy");

JavaCopy javaCopy = new JavaCopy("123", 123);
javaCopy.setDate(new Date());
javaCopy.setTestcopy(testcopy);
JavaCopy javaCopy1 = javaCopy.clone();

System.out.println("===javaCopy1===" + javaCopy1.getName() + "age"
+ javaCopy1.getAge() + "date" + javaCopy1.getDate());

javaCopy1.setName("321");
javaCopy1.setAge(321);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}

javaCopy.setDate(new Date());
javaCopy.getTestcopy().setName("javaCopy1");
System.out.println("===javaCopy=== name" + javaCopy.getName());
System.out.println("===javaCopy1=== name" + javaCopy1.getName());

System.out.println("===javaCopy=== age" + javaCopy.getAge());
System.out.println("===javaCopy1=== age" + javaCopy1.getAge());

System.out.println("===javaCopy=== date" + javaCopy.getDate());
System.out.println("===javaCopy1=== date" + javaCopy1.getDate());

System.out.println("===javaCopy=== testcopy name" + javaCopy.getTestcopy().getName());
System.out.println("===javaCopy1=== testcopy name" + javaCopy1.getTestcopy().getName());
}
}

执行的结果:

===javaCopy1===123age123dateTue Jan 05 13:52:09 GMT+08:00 2016
===javaCopy=== name123
===javaCopy1=== name321
===javaCopy=== age123
===javaCopy1=== age321
===javaCopy=== dateTue Jan 05 13:52:11 GMT+08:00 2016
===javaCopy1=== dateTue Jan 05 13:52:09 GMT+08:00 2016
===javaCopy=== testcopy namejavaCopy1
===javaCopy1=== testcopy namejavaCopy1


注意添加的粗字体的代码(深拷贝)


public JavaCopy clone(){
JavaCopy javaCopy = null;
try {
javaCopy = (JavaCopy)super.clone();

} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return javaCopy;
}

执行结果:

===javaCopy=== dateTue Jan 05 13:55:15 GMT+08:00 2016
===javaCopy1=== dateTue Jan 05 13:55:13 GMT+08:00 2016
===javaCopy=== testcopy namejavaCopy1
===javaCopy1=== testcopy namejavaCopy


jdk中的arraylist深拷贝实现:

public Object clone() {
try {
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();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: