【问题标题】:Java Object#clone behavior?Java Object#clone 行为?
【发布时间】:2017-02-11 22:57:15
【问题描述】:

我正在测试 Object#clone 方法的行为,但我不明白为什么以下代码打印为 true, Diego, Diego,我期待它打印 true, Diego, Armando,因为 p.getName() == p2 .getName() 打印为真。请任何人解释为什么 p2.setName("Armando") 不修改 p 对象,如果它们指向相同的字符串?谢谢。

public class Main {

public static void main(String[] args) {
    Person p = new Person();
    p.setName("Diego");
    Person p2 = null;
    try {
         p2 = (Person) p.clonar();
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
    System.out.println(p.getName() == p2.getName());
    System.out.println(p.getName());
    p2.setName("Armando");
    System.out.println(p.getName());
}
}

class Person implements Cloneable {
private String name;

public Object clonar() throws CloneNotSupportedException {
    return this.clone();
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}
}

【问题讨论】:

  • 您设置的名称是p2,而不是p,所以名称不会更改...
  • 但据我了解,克隆方法会进行浅拷贝,因此两个对象都指向同一个字符串
  • 一个对象不等于它的克隆,所以p2 != p。因此,设置p2 的名称不会影响p 的名称。
  • 因为当时两个引用都指向同一个 String 对象。但是,当您调用 p2.setName 时,p2 的名称引用将指向另一个 String 对象。
  • 应该是这样,是的。

标签: java clone


【解决方案1】:

因为当时两个引用都指向同一个 String 对象。但是,当您调用 p2.setName 时,p2 的名称引用将指向另一个 String 对象。 @dunni 提供的答案

为了重现我想要的行为,我首先需要添加一个可变类作为占位符(地址):

public class Main {

public static void main(String[] args) {
    Person p = new Person();
    Person p2 = null;
    Address address = new Address("paseo de la reforma");
    p.setAddress(address);

    try {
         p2 = (Person) p.clonar();
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }   
    p2.getAddress().setStreet("lomas de chapultepec");
    System.out.println(p.getAddress().getStreet());
}
}

class Address {
private String street;

public Address(String street) {
    this.street = street;
}

public String getStreet() {
    return street;
}

public void setStreet(String street) {
    this.street = street;
}

  }

class Person implements Cloneable {
private String name;
private Integer edad;
private int mes;
private Address address;

public Integer getEdad() {
    return edad;
}

public void setEdad(Integer edad) {
    this.edad = edad;
}

public int getMes() {
    return mes;
}

public void setMes(int mes) {
    this.mes = mes;
}

public Object clonar() throws CloneNotSupportedException {
    return this.clone();
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public Address getAddress() {
    return address;
}

public void setAddress(Address address) {
    this.address = address;
}
}

现在打印:

改革大道

洛马斯·德·查普尔特佩克

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-06
    • 2011-11-16
    • 1970-01-01
    • 1970-01-01
    • 2022-12-01
    • 1970-01-01
    • 2014-03-18
    • 2015-07-16
    相关资源
    最近更新 更多