昨天同事遇到了一个奇怪的问题,他需要将一个JavaBean拷贝一份,然后对新创建的Bean进行操作。但是他对新的Bean操作后,会影响旧的Bean的值。当听到这个问题的时候,我第一反应就是他的拷贝方法有问题,只是将aBean的内容复制给了bBean,但是在内存中指向的是同一个地址。这里就引出了两个关键词,浅拷贝和深拷贝。
被复制对象的所有变量值都和原来的对象的值相同,但是复制后的对象的引用仍然指向原来的对象。简单来说,就是对A进行拷贝生成B,只是将A的值复制给了B,内存中指向的是同一地址,影响就是改变B的同时,A的值也会改变。
被复制对象的所有变量值都和原来的对象的值相同,除了变量的值改变,也会创建新的指向变量的地址。源对象A和复制后的B,虽然内容是一样的,但是各自指向的地址不同,所以改变相互不受影响。
那问题已经知道,Java的Bean对象要怎么进行深拷贝呢。
①利用Object类的clone()方法。 ②在派生类中重写基类的clone方法,并声明为public。 ③在派生类的clone()方法中,调用super.clone()。 ④在派生类中实现Cloneable接口。
这是一个Student的类,重写了clone()方法。
public class Student implements Cloneable { private String name; private int age; public Student(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Object clone() { Object o = null; try { o = (Student)super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return o; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }测试clone
public static void main(String[] args) { Student s1=new Student("张三",18); System.out.println("修改前s1值:" + s1.toString()); Student s2=(Student)s1.clone(); s2.setName("李四"); s2.setAge(20); //修改学生2后,不影响学生1的值。 System.out.println("修改后s1值:" + s1.toString()); System.out.println("s2的值:" + s2.toString()); }控制台输出的结果如下:
修改前s1值:Student [name=张三, age=18] 修改后s1值:Student [name=张三, age=18] s2的值:Student [name=李四, age=20]上面的例子对象中的属性是基本类型,但是如果包含非基本类型,结果怎样呢,上代码,对Student类进行修改,加入Course类。Student类
public class Student implements Cloneable { private String name; private int age; private Course course; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Course getCourse() { return course; } public void setCourse(Course course) { this.course = course; } public Student(String name, int age, Course course) { super(); this.name = name; this.age = age; this.course = course; } public Student() { } public Object clone() { Object o = null; try { o = (Student)super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return o; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + ", course=" + course + "]"; } }Course类
public class Course { private String name; private int value; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public Course(String name, int value) { super(); this.name = name; this.value = value; } public Course() { } @Override public String toString() { return "Course [name=" + name + ", value=" + value + "]"; } }测试克隆
public static void main(String[] args) { Student s1 = new Student(); s1.setName("张三"); s1.setAge(24); Course c = new Course(); c.setName("语文"); c.setValue(80); s1.setCourse(c); System.out.println("修改前s1值:" + s1.toString()); Student s2 = (Student)s1.clone(); s2.setName("李四"); s2.setAge(20); Course c2 = s2.getCourse(); c2.setName("数学"); c2.setValue(90); //修改学生2的Course后,影响学生1的Course。 System.out.println("修改后s1值:" + s1.toString()); System.out.println("s2的值:" + s2.toString()); }控制台输出结果
修改前s1值:Student [name=张三, age=24, course=Course [name=语文, value=80]] 修改后s1值:Student [name=张三, age=24, course=Course [name=数学, value=90]] s2的值:Student [name=李四, age=20, course=Course [name=数学, value=90]]为了解决上面的问题,我们需要使用深度克隆方案。修改之后的Student类和Course类如下 Student类
public class Student implements Cloneable { private String name; private int age; private Course course; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Course getCourse() { return course; } public void setCourse(Course course) { this.course = course; } public Student(String name, int age, Course course) { super(); this.name = name; this.age = age; this.course = course; } public Student() { } public Student clone() { Student s = null; try { s = (Student)super.clone(); s.course = course.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return s; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + ", course=" + course + "]"; } }Course类
public class Course implements Cloneable{ private String name; private int value; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } public Course(String name, int value) { super(); this.name = name; this.value = value; } public Course() { } public Course clone() { Course c = null; try { c = (Course)super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return c; } @Override public String toString() { return "Course [name=" + name + ", value=" + value + "]"; } }测试方法使用之前的方法,下面的运行后的结果。
修改前s1值:Student [name=张三, age=24, course=Course [name=语文, value=80]] 修改后s1值:Student [name=张三, age=24, course=Course [name=语文, value=80]] s2的值:Student [name=李四, age=20, course=Course [name=数学, value=90]]根据结果可知,通过深度克隆后,clone后的对象非基本类的变量修改,不会对原对象造成影响。
转载于:https://www.cnblogs.com/ghq120/p/11603961.html