Java的克隆与C+的拷贝之间的区别
有的人会误认两者是同样的东西,Java有深克隆、浅克隆,C+有深拷贝、浅拷贝,这里为大家详细介绍一下两者的区别。
首先带着大家复习一下C+中深拷贝和浅拷贝的区别
在对一个对象进行拷贝时,拷贝的结果仅仅是将这个对象的地址赋给拷贝对象,在对拷贝对象进行修改的时候,原对象也会做出相应的改变,这就是浅拷贝。
为了拷贝能得到一个地址不一样的新的对象,需要重写拷贝构造函数,创建一个新的对象一一赋值再返回,这就是深拷贝。
C+中可以通过重载运算符完成深拷贝,Java中没有运算符重载该如何完成深拷贝呢?
Java中提供了clone方法来完成深拷贝的功能,但是clone也分为深克隆和浅克隆。分别是怎么实现的下面通过两个例子为大家讲解。
对象要实现克隆首先要继承clonable的接口,然后重写clone方法。
浅克隆
浅克隆得到的对象与原对象的地址不同,但是成员变量为基本数据类型的时候,直接赋值给克隆对象,成员变量为引用类型的时候,会把该引用类型的地址赋给克隆对象。也就是 对象完成了深拷贝,但是对象中的对象还是浅拷贝。
public class Main{
public static void main(String[] args) throws Exception {
Pet pet = new Pet("xiaohuang","dog");
Person person1 = new Person(pet, "zhangsan");
Person person2 = (Person)person1.clone();
person2.getPet().setType("cat");
System.out.println(person1);
System.out.println(person2);
}
}
class Person implements Cloneable{
private Pet pet;
private String name;
public Person(Pet pet,String name) {
// TODO Auto-generated constructor stub
this.pet = pet;
this.name = name;
}
@Override
public Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
@Override
public String toString() {
// TODO Auto-generated method stub
return"name = " + name + ", pet[" + pet.toString() + "]";
}
public Pet getPet() {
return pet;
}
public void setPet(Pet pet) {
this.pet = pet;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Pet implements Cloneable{
private String nickname;
private String type;
public Pet(String nickname,String type) {
// TODO Auto-generated constructor stub
this.nickname = nickname;
this.type = type;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "nickname =" + nickname + ",type = " + type;
}
}
运行结果如下:
name = zhangsan, pet[nickname =xiaohuang,type = cat]
name = lisi, pet[nickname =xiaohuang,type = cat]
深克隆
深克隆的实现也很简单,重载对象的clone即可。
public class Main{
public static void main(String[] args) throws Exception {
Pet pet = new Pet("xiaohuang","dog");
Person person1 = new Person(pet, "zhangsan");
Person person2 = (Person)person1.clone();
person2.getPet().setType("cat");
person2.setName("lisi");
System.out.println(person1);
System.out.println(person2);
}
}
class Person implements Cloneable{
private Pet pet;
private String name;
public Person(Pet pet,String name) {
// TODO Auto-generated constructor stub
this.pet = pet;
this.name = name;
}
@Override
public Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
Person person = (Person)super.clone();
person.setPet((Pet)this.pet.clone());
return person;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return"name = " + name + ", pet[" + pet.toString() + "]";
}
public Pet getPet() {
return pet;
}
public void setPet(Pet pet) {
this.pet = pet;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Pet implements Cloneable{
private String nickname;
private String type;
public Pet(String nickname,String type) {
// TODO Auto-generated constructor stub
this.nickname = nickname;
this.type = type;
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "nickname =" + nickname + ",type = " + type;
}
}
运行结果
name = zhangsan, pet[nickname =xiaohuang,type = dog]
name = lisi, pet[nickname =xiaohuang,type = cat]
通过对结果的观察,就会发现已经实现了深克隆。在用到clone方法的时候要多注意噢


被折叠的 条评论
为什么被折叠?



