2017-02-11 123 views
-1

我正在测试对象#克隆方法的行为,我不明白为什么下面的代码打印真实,迭戈,迭戈,我期待它打印真正的迭戈,阿曼多自p.getName()== p2。 getName()打印真实。任何人都可以请任何人解释为什么p2.setName(“Armando”)不修改p对象,如果他们指向相同的字符串?谢谢。Java对象#克隆行为?

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; 
} 
} 
+1

您设置的'p2',不'p'的名称,这样的名字没有改变... – Li357

+0

但正如我理解C单独的方法使浅拷贝,因此两个对象指向相同的字符串 –

+0

一个对象不等于它的克隆,所以'p2!= p'。因此,设置'p2'的名字不会影响'p'的名字。 – Li357

回答

0

因为当时两个引用都指向同一个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; 
} 
} 

这现在的打印效果:

的Paseo de la雷福马

洛马斯 - 查普尔特佩克