java - 对 Java 中的克隆感到困惑

标签 java clone cloning

我在 Java 中有这段代码。

public class CloneTest implements Cloneable{
    String name;
    int marks;
    public CloneTest(String s, int i) {
        name = s;
        marks = i;
    }

    public void setName(String s) {
        name = s;
    }

    public void setMarks(int i) {
        marks = i;
    }

    @Override
    public Object clone() {
        return new CloneTest(this.name, this.marks);
    }
}

我创建了这个类的一个对象,然后克隆了它。现在,当我在一个对象中更改 name 的值时,name 的值在另一个对象中保持不变。奇怪的是在构造函数中,我只是为 name 使用一个简单的引用,而不是为 name 创建一个新的 String。现在,由于 String 是引用类型,我希望克隆中的 String 也被更改。谁能告诉我这是怎么回事?提前致谢!

编辑

代码测试

CloneTest real = new CloneTest("Molly", 22);
CloneTest clone = real.clone();
real.setName("Dolly");

我使用 BlueJ 的“检查变量”功能来检查值。

最佳答案

假设 original 是原始 CloneTest 对象的名称,cloned 是您使用 original 创建的克隆对象>clone() 方法。

事情是这样的:
1. 你的 cloned.nameoriginal.name 指向同一个对象,在本例中是一个字符串。
2. 然后你要求你的 original.name 指向一个不同的字符串对象(“Dolly”)。当您将新的字符串对象(“Dolly”)分配给引用 original.name 时会发生这种情况。
3. 但是,cloned.name 仍然指向第一个字符串对象(“Dolly”)。

因此,cloned.name 仍然打印第一个 String 对象。

现在,如果您能够在不重新分配引用的情况下更改 String 对象的内容,那么 clone.name 中的更改将反射(reflect)在 original.name 中。但是对于 String 对象,由于 String 的不可变性,这是不可能的。但是,您可以使用 StringBuffers 反射(reflect)从 cloneoriginal 的变化。可以说是可变字符串。看一下这个示例代码:https://gist.github.com/VijayKrishna/5967668

关于java - 对 Java 中的克隆感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17573955/

相关文章:

c# - 如何在不将类标记为可序列化的情况下对其进行深度复制

java - Neo4j 查询在浏览器中运行良好,但在 Spring Data Neo4j 中运行不佳

java - 使用解析的信息填充 JTable

JQuery Mobile 克隆页面

java - 单例合约可以被打破吗?如果是,有多少种方式?

C# 将 System.Data.Entity.DynamicProxies 克隆到实际(非代理)类?

java - 正则表达式在intellij idea中编译,但不在android studio中编译并显示

java - 创建新的 SpannableStringBuilder 返回 null

java - 如何使用 RestS3Service 克隆 Amazon S3 中的对象

javascript - 克隆元素后在文档中找到原始元素