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

java中的Clone(深拷贝,浅拷贝)

2016-08-16 00:00 363 查看
摘要: java中的Clone(深拷贝,浅拷贝)

随着现代科技的发展,人类已经能够克隆(clone)牛,羊等动物。Java是面向对象,也能够实现对象的克隆(clone),在之前的学习中见到引用的赋值操作,如下例所示:

首先定义一个Student类

public class Student implements Cloneable{

private String studentName;

private int age;

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getStudentName() {

return studentName;

}

public void setStudentName(String studentName) {

this.studentName = studentName;

}

}

入口函数:

public static void main(String args[]){

Student student0 = new Student();

student0.setStudentName("xiaoming");

Student student1 = student0;

System.out.println("student0.getStudentName:"+student0.getStudentName());

System.out.println("student1.getStudentName:"+student1.getStudentName());

运行结果:打印输出:

student0.getStudentName:xiaoming

student1.getStudentName:xiaoming

在入口函数中student0 被付给了student1两引用指向了内存中的同一块空间,所以通过student0对对象的操作与通过student1对对象的操作完全一致。

有时候需要创造一个student0的副本,内容与student0完全一致,但是以后可以根据需要对student1内容修改,而不会影响到student0,这时候我们就需要用到clone.

虽然Clone方法在Object中存在的,但是如果想要调用clone必须实现Cloneable接口,否则会抛出java.lang.CloneNotSupportedException。

看一下实例

public class Student implements Cloneable{

private String studentName;

private int age;

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getStudentName() {

return studentName;

}

public void setStudentName(String studentName) {

this.studentName = studentName;

}

protected Object clone() throws CloneNotSupportedException {

Student student = (Student) super.clone();

return student;

}

}

入口函数:

public static void main(String args[]){

Student student = new Student();

student.setAge(10);

student.setStudentName("xiaobai");

try {

Student s1 = (Student) student.clone();

System.out.println("student.studentName:"+student.getStudentName());

System.out.println("student.age:"+student.getAge());

System.out.println("s1.studentName:"+s1.getStudentName());

System.out.println("s1.age:"+s1.getAge());

} catch (CloneNotSupportedException e) {

e.printStackTrace();

}

}

打印运行输出结果:

student.studentName:xiaobai

student.age:10

s1.studentName:xiaobai

s1.age:10

我们可以看出,student 和s1的内容完全一致,而且我们可以修改s1的值,而不会影响student的值。

修改入口函数:

public static void main(String args[]){

Student student = new Student();

student.setAge(10);

student.setStudentName("xiaobai");

try {

Student s1 = (Student) student.clone();

s1.setStudentName("xiaohei");

System.out.println("student.studentName:"+student.getStudentName());

System.out.println("student.age:"+student.getAge());

System.out.println("s1.studentName:"+s1.getStudentName());

System.out.println("s1.age:"+s1.getAge());

} catch (CloneNotSupportedException e) {

e.printStackTrace();

}

}

运行结果:

student.studentName:xiaobai

student.age:10

s1.studentName:xiaohei

s1.age:10

我们发现s1的studentName值得到了修改,但是student的studentName值没有受到影响,这就是clone的作用。使用起来很简单,只需要在需要clone的对象上实现(implements)Cloneable接口,然后再在类中加上clone方法,在方法中只需要调用super.clone()即可,如上例中的部分代码:Student student = (Student) super.clone(),需要注意clone方法在当前类没有实现Cloneable的情况下可能抛出CloneNotSupportedException,所以我们需要对该异常进行处理。以上的Student类中只有基本属性,这种拷贝被称为浅拷贝。

深拷贝

如果对象中有其他对象的引用,使用浅拷贝无法完成对象的整个克隆,因为如果使用浅拷贝,只是对象的引用得到的拷贝,而两个引用是指向了同一个对象,对其中一个修改还是会影响到另外一个对象。这时后我们需要引入深拷贝,深拷贝实现起来也比较简单,只需要对对象中的对象再次进行clone操作。看以下实例

Glasses类代码如下:

public class Glasses implements Cloneable {

private String color;

public String getColor() {

return color;

}

public void setColor(String color) {

this.color = color;

}

protected Object clone() throws CloneNotSupportedException {

return super.clone();

}

}

在Student类中包含Glasses,代码如下:

public class Student implements Cloneable{

private String studentName;

private Glasses glasses;

private int age;

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getStudentName() {

return studentName;

}

public void setStudentName(String studentName) {

this.studentName = studentName;

}

public Glasses getGlasses() {

return glasses;

}

public void setGlasses(Glasses glasses) {

this.glasses = glasses;

}

protected Object clone() throws CloneNotSupportedException {

Student student = (Student) super.clone();

student.glasses= (Glasses) glasses.clone();

return student;

}

}

如果想对Glasses进行拷贝,而不是仅仅克隆Glasses的引用,在clone方法中增加了student.glasses= (Glasses) glasses.clone();

入口函数:

public static void main(String args[]){

Student student = new Student();

student.setAge(10);

student.setStudentName("xiaobai");

Glasses glasses = new Glasses();

glasses.setColor("red");

student.setGlasses(glasses);

try {

Student s1 = (Student) student.clone();

s1.setStudentName("xiaohei");

System.out.println("s1.color:"+s1.getGlasses().getColor());

} catch (CloneNotSupportedException e) {

e.printStackTrace();

}

}

运行输出:

s1.color:red

通过以上实例,可以看出student中Glasses的color值被完全克隆给了s1,所以s1的Glasses的color也是red。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: