Java';对象。克隆';vs等于(';=…';)

Java';对象。克隆';vs等于(';=…';),java,clone,Java,Clone,最近一位朋友问我为什么C#中没有克隆函数。但我真的不明白为什么要使用克隆,除了以下几点: SomeClass cls = new SomeClass(); SomeClass cls2 = cls; 为什么要使用=cls.clone();,所以像这样: SomeClass cls = new SomeClass(); SomeClass cls2 = (SomeClass) cls.clone(); 我从来都不明白其中的区别。有人能解释一下哪一个更好,区别是什么吗?clone()提供原始对象

最近一位朋友问我为什么C#中没有克隆函数。但我真的不明白为什么要使用克隆,除了以下几点:

SomeClass cls = new SomeClass();
SomeClass cls2 = cls;
为什么要使用=cls.clone();,所以像这样:

SomeClass cls = new SomeClass();
SomeClass cls2 = (SomeClass) cls.clone();

我从来都不明白其中的区别。有人能解释一下哪一个更好,区别是什么吗?

clone()
提供原始对象的浅拷贝。变量的状态将与原始变量的状态相同
newmyclassobject()
返回一个新对象,而不是克隆或复制的对象。

您在这里做了什么

SomeClass cls = new SomeClass();
SomeClass cls2 = cls;
正在为同一个对象创建两个引用。图片(可能有点难看,因为是我自己画的;):

但在本规范中:

SomeClass cls = new SomeClass();
SomeClass cls2 = (SomeClass) cls.clone();
您创建了两个具有两个引用的对象,其中第二个对象是第一个对象的副本。cls指向第一个对象,而cls2指向第二个对象。Jvm必须为两个不同的对象而不是一个对象保留空间。图片:


问题始终是您是否希望对一个对象的更改影响另一个对象(对于可变对象)。比如说

SomeClass cls = new SomeClass();
SomeClass cls2 = cls; //copies the reference, not the object
cls2.doubleEverything();
在上面的示例中,只有一个对象,因此
cls2
引用的对象中的所有内容都加倍,这是
cls1
引用的同一个对象,因此它们都看到了更改

SomeClass cls = new SomeClass();
SomeClass cls2 = (SomeClass) cls.clone();
cls2.doubleEverything();
两个变量引用了两个对象,对(cls2引用的对象)的更改不会影响cls

所有这一切都假定
clone
正确实施,“正确”的定义会根据具体情况而变化。它可能只是一个肤浅的副本,请始终警惕
.clone()

这是对对象SomeClass的引用

 SomeClass cls2 = cls;
这是对同一对象的引用

这是对从原始对象克隆的其他对象的引用。考虑下一个案例

 cls2.setState(newState)
在这种情况下,您将更改原始对象(由
cls
cls2
引用)

在这种情况下,只会更改
cls3
。原始对象(
cls
cls2
)将不会更改

 SomeClass cls3 = (SomeClass) cls.clone();
 cls2.setState(newState)
cls3.setState(newState)