Java:浅拷贝(克隆)不适合我?
根据定义: 浅复制是只将字段值从一个对象复制到另一个对象的复制。它们是不同的对象,但问题是,当我们更改任何原始地址的属性时,这也会影响shallowCopy的地址 我试着看看对象1和对象2的值是否变得相同,所以我试着跟随,但无法这样做Java:浅拷贝(克隆)不适合我?,java,clone,shallow-copy,Java,Clone,Shallow Copy,根据定义: 浅复制是只将字段值从一个对象复制到另一个对象的复制。它们是不同的对象,但问题是,当我们更改任何原始地址的属性时,这也会影响shallowCopy的地址 我试着看看对象1和对象2的值是否变得相同,所以我试着跟随,但无法这样做 public class TestClone implements Cloneable { private String a; public String getA() { return a; } public
public class TestClone implements Cloneable {
private String a;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
主程序:
package com.test;
public class MainTestClone {
public static void main(String[] args) throws CloneNotSupportedException {
TestClone clone = new TestClone();
clone.setA("RABA");
TestClone clone2 = (TestClone) clone.clone();
System.out.println(clone.getA());
System.out.println(clone2.getA());
System.out.println("---------------------------");
clone.setA("DABA");
System.out.println(clone.getA());
System.out.println(clone2.getA());
System.out.println("---------------------------");
clone2.setA("Clone2 RABA DABA");
System.out.println(clone.getA());
System.out.println(clone2.getA());
}
}
输出:
RABA
RABA
---------------------------
DABA
RABA <--- It does not change to DABA
---------------------------
DABA <--- No Changes here
Clone2 RABA DABA
根据Java文档
创建并返回此对象的副本
因此,对旧对象所做的任何更改都将独立于新克隆的对象。
所以克隆、克隆2是保存在不同内存空间中的独立Java对象
如果您正在查看复制对克隆2的更改,请将引用指向同一对象。
例如
根据Java文档
创建并返回此对象的副本
因此,对旧对象所做的任何更改都将独立于新克隆的对象。
所以克隆、克隆2是保存在不同内存空间中的独立Java对象
如果您正在查看复制对克隆2的更改,请将引用指向同一对象。
例如
浅拷贝是关于共享内部引用的。如果直接更改引用,克隆将保留在旧引用上,因为它是另一个对象 这就是为什么Java中称为浅拷贝或浅克隆的原因。如果只有原语类型字段或不可变对象,那么Java中的浅拷贝和深拷贝就没有区别。这就是为什么这里你有一个深度副本 例如,如果用日期替换字符串,然后修改日期内容而不是引用。类似于obj1.Date.setTime1的内容,克隆对象将反映更改,因为它指向相同的日期引用 我们可以看到这样的副本 在浅拷贝上clone2.date=clone.date
在深度复制clone2.date=new Dateclone.getTime 浅层复制是关于共享内部引用的。如果直接更改引用,克隆将保留在旧引用上,因为它是另一个对象 这就是为什么Java中称为浅拷贝或浅克隆的原因。如果只有原语类型字段或不可变对象,那么Java中的浅拷贝和深拷贝就没有区别。这就是为什么这里你有一个深度副本 例如,如果用日期替换字符串,然后修改日期内容而不是引用。类似于obj1.Date.setTime1的内容,克隆对象将反映更改,因为它指向相同的日期引用 我们可以看到这样的副本 在浅拷贝上clone2.date=clone.date
在深度复制clone2.date=new Dateclone.getTime 我认为真正的问题在于,你断章取义地曲解了以下定义: 浅复制是只将字段值从一个对象复制到另一个对象的复制。它们是不同的对象,但问题是,当我们更改任何原始地址的属性时,这也会影响shallowCopy的地址 这显然是指一些例子。。。你没有引用过。因此,我的评论是你断章取义了 要使此描述正确,原始地址的属性字段必须与要克隆的对象分开。我想这个例子是这样的:
public class User implements Cloneable {
String name;
Address address;
...
public User clone() {
return (User)(super.clone());
}
}
public class Address {
String street;
String city;
String zipCode;
}
他们正在这样做:
Address address = new Address(...);
User user = new User("Fred", address);
User shallowCopy = user.clone();
然后
user.getAddress().setZipCode(...);
并注意到这会更改与原始用户对象和克隆用户对象关联的邮政编码
注意,我们正在更改地址的属性,而不是用户的属性。正如引用的文本明确指出的那样
但你的例子不同。分别更改原始对象和克隆对象的字段。并注意到分配一个不会影响另一个
你现在所做的相当于
shallowCopy.setAddress(new Address(...));
如果这样做,shallowCopy引用的对象将不再是用户引用的对象的浅层副本,并且user.getAddress.setZipCode。。。将不再影响shallowCopy的邮政编码,反之亦然
简言之,你看到与定义所说的不同的东西的原因是你在做不同的事情
克隆完全按照指定的方式工作。问题在于您误解了或误用了浅层复制的定义。我认为真正的问题在于您断章取义地误解了以下定义: 浅复制是只将字段值从一个对象复制到另一个对象的复制。它们是不同的对象,但问题是,当我们更改任何原始地址的属性时,这也会影响shallowCopy的地址 这显然是指一些例子。。。你没有引用过。因此,我的意见是,你没有 断章取义 要使此描述正确,原始地址的属性字段必须与要克隆的对象分开。我想这个例子是这样的:
public class User implements Cloneable {
String name;
Address address;
...
public User clone() {
return (User)(super.clone());
}
}
public class Address {
String street;
String city;
String zipCode;
}
他们正在这样做:
Address address = new Address(...);
User user = new User("Fred", address);
User shallowCopy = user.clone();
然后
user.getAddress().setZipCode(...);
并注意到这会更改与原始用户对象和克隆用户对象关联的邮政编码
注意,我们正在更改地址的属性,而不是用户的属性。正如引用的文本明确指出的那样
但你的例子不同。分别更改原始对象和克隆对象的字段。并注意到分配一个不会影响另一个
你现在所做的相当于
shallowCopy.setAddress(new Address(...));
如果这样做,shallowCopy引用的对象将不再是用户引用的对象的浅层副本,并且user.getAddress.setZipCode。。。将不再影响shallowCopy的邮政编码,反之亦然
简言之,你看到与定义所说的不同的东西的原因是你在做不同的事情
克隆完全按照指定的方式工作。问题是您误解或误用了浅层复制的定义。您所实现的只是浅层复制。更改原始对象的属性不会影响复制对象的状态,因为它只包含不可变字段。如果它包含任何可变对象,则会影响它们两个
如果尝试添加任何类类型的另一个字段,并尝试更改该类字段的值,则更改将反映在clone和clone2对象中 您所实现的只是浅层复制。更改原始对象的属性不会影响复制对象的状态,因为它只包含不可变字段。如果它包含任何可变对象,则会影响它们两个
如果尝试添加任何类类型的另一个字段,并尝试更改该类字段的值,则更改将反映在clone和clone2对象中 谢谢。我试图实现这样一种说法,即在浅层复制中,我们对对象所做的更改也将在克隆引用中看到;这将达到目的,因此,无论您对旧对象做什么更改,都将独立于新对象,而不是完全真实的。例如,如果字符串被日期替换,并且您修改了日期内容而没有更改引用,则克隆将看到相同的更改。@CodeScale是否确定两个克隆对象共享相同的内存?浅拷贝共享引用。。如果您修改引用的内容,两个都将看到更改。谢谢。我试图实现这样一种说法,即在浅层复制中,我们对对象所做的更改也将在克隆引用中看到;这将达到目的,因此,无论您对旧对象做什么更改,都将独立于新对象,而不是完全真实的。例如,如果字符串被日期替换,并且您修改了日期内容而没有更改引用,则克隆将看到相同的更改。@CodeScale是否确定两个克隆对象共享相同的内存?浅拷贝共享引用。。如果修改引用的内容,两者都将看到更改。