日期:2014-05-20  浏览次数:20644 次

java对象克隆及内存布局的问题
[code=Java][/code]
public class CloneTest2{
public static void main(String[] args) throws Exception{
Teacher teacher = new Teacher();

teacher.setAge(40);
teacher.setName("Teacher zhang");

Student2 s1 = new Student2();

s1.setAge(20);
s1.setName("zhangsan");
s1.setTeacher(teacher);

Student2 s2 = (Student2)s1.clone();

System.out.println(s2.getName());
System.out.println(s2.getAge());

teacher.setName("Teacher Li");

System.out.println(s2.getTeacher().getName());
System.out.println(s2.getTeacher().getAge());
}
}
class Teacher implements Cloneable{
private int age;
private String name;

public int getAge(){
return age;
}
  public void setAge(int age){
this.age = age;
}
  public String getName(){
return name;
}
  public void setName(String name){
this.name = name;
}
  public Object clone() throws CloneNotSupportedException{
return super.clone();
}
}

class Student2 implements Cloneable{
private int age;
private String name;
private Teacher teacher;

public int getAge(){
return age;
}
  public void setAge(int age){
this.age = age;
}
  public String getName(){
return name;
}
  public void setName(String name){
this.name = name;
}
  public Teacher getTeacher(){
return teacher;
}
public void setTeacher(Teacher teacher){
this.teacher = teacher;
}
public Object clone() throws CloneNotSupportedException{
Student2 student2 = (Student2)super.clone();
student2.setTeacher((Teacher)student2.getTeacher().clone());
return student2;
}
}

为什么s2.getTeacher().getName()不是li而是zhang,此时内存中的布局是怎么样的 ?
[code=Java][/code]
public class CloneDemo{
public static void main(String args[])throws Exception{
Person p1 = new Person();
p1.setName("zhangsan");
p1.setAge(11);

Person p2 = (Person)p1.clone();
p2.setName("lisi");
//System.out.println(p2.getName().equals(p1.getName()));
System.out.println(p1.getName());
System.out.println(p2.getName());
System.out.println(p2.getAge());
}
}
class Person implements Cloneable{
private int age;
private String name;
public void setAge(int age){
this.age = age;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return this.age;
}
public String getName(){
return this.name;
}
public Object clone()throws CloneNotSupportedException{
return super.clone();
}
}

为什么p1.getName()还是zhang呢。浅克隆 他们两个不是还指向同一个Person对象么  
为什么值会不一样 。
说到底可能还是我不懂此时内存中的布局 。
麻烦大家帮我看看



------解决方案--------------------
System.out.println(s2.getTeacher().getName());
System.out.println(s2.getTeacher().getAge());

s2中的深拷贝,他的teacher是新的对象。
楼主更改的teacher对象,是s1中的对象。
System.out.println(s1.getTeacher().getName());
这个是楼主更改的值。


浅拷贝,只拷贝 原始数据类型的数据,以及成员变量的引用。
深拷贝,除了 原始数据类型之外,还要生成新的成员变量对象,并将新对象的值拷贝过来。
------解决方案--------------------
虽然是浅拷贝,但是因为setName方法是直接改变属性的指向,所以调用setName方法的对象属性指向变了,但是没调用setName的属性指向还是原来的
调用clone方法,p1和p2是两个不同的对象,所以内存空间不一样,所以p1的name和p2的name是两个不同内存空间的数据域(属性),但是p1的name和p2的name都指向相同的对象zhang
p2调用setName方法,
public void setName(String name){
this.name = name; //这里把p2的name属性指向新的对象lisi,但是p1的name的还是指向zhang没变
}
------解决方案--------------------