欢迎各位猿哥指教批评
1、在我们的开发过程中经常遇到要复制一个对象
比如:
@Test
public void test1(){
People p1 = new People("1","zhang3",12);
People p2 = p1 ;
System.out.println(p1==p2);// 输出 true
p1.setUsername("li4");
System.out.println(p2.getUsername()); // 输出 li4
}
上面这段代码得到的结果是:
图1
将p1这个引用传给了 p2 , p1和p2 指向了栈中的同一个内存对象。当我们改变 p1中 username的值是 p2中的值也发生了改变。
很显然 我们要的并不是这样的结果,那么我们如何才能得到下图所示的结果呢
图2
2、浅克隆 :对象进行自我复制 ,返回一个新对象。新对象的所有变量都与自己的变量值相同,而新对象所有对其他对象的引用仍然和原对象的引用值一样。
实现浅克隆的三个步骤:
@Override
public Object clone() throws CloneNotSupportedException {
People p = null;
try {
p = (People) super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return p ;
}
@Test
public void test2()throws CloneNotSupportedException{
People p1 = new People("1","zhang3",12);
People p2 = (People) p1.clone();
System.out.println(p1==p2);// 输出 false
p1.setUsername("li4");
System.out.println(p2.getUsername()); // 输出 zhang3
}
如此调整之后 p1和p2就是2个不同的引用,分别指向2个不同内存空间中的对象 ,当我们对其中某一个对象变量更改的时候不会影响另一个。 前面我们说 浅克隆概念的时候还有一个特性,那就是 新对象所有对其他对象的引用仍然和原对象的引用值一样。这个是什么意思呢?请看下面这个例子:
我们首先创建一个student对象 ,并作为属性 放入 People中
package com.wcly.activemqTest;
public class Student {
private String classNo;
private String teacherName ;
public String getTeacherName() {
return teacherName;
}
public void setTeacherName(String teacherName) {
this.teacherName = teacherName;
}
public String getClassNo() {
return classNo;
}
public void setClassNo(String classNo) {
this.classNo = classNo;
}
public Student(String classNo, String teacherName) {
this.classNo = classNo;
this.teacherName = teacherName;
}
}
package com.wcly.activemqTest;
public class People implements Cloneable{
private String id;
private String username;
private int age;
private Student stu ;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Student getStu() {
return stu;
}
public void setStu(Student stu) {
this.stu = stu;
}
public People(String id, String username, int age,Student stu) {
this.id = id;
this.username = username;
this.age = age;
this.stu = stu ;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if(obj instanceof People) {
People b = (People) obj ;
if (this.getId() == b.getId()
&& this.getUsername().equals(b.getUsername())
&& this.getAge() == b.getAge()) {
return true;
}
}
return false;
}
@Override
public Object clone() throws CloneNotSupportedException {
People p = null;
try {
p = (People) super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return p ;
}
}
接下来我们进行测试:
@Test
public void test3()throws CloneNotSupportedException{
People p1 = new People("1","zhang3",12,new Student("1","teacher"));
People p2 = (People) p1.clone();
System.out.println(p1==p2);// 输出 false
p1.setUsername("li4");
System.out.println(p2.getUsername()); // 输出 zhang3
p1.getStu().setClassNo("2");
System.out.println(p2.getStu().getClassNo()); // 输出 2
System.out.println(p1.getStu()==p2.getStu());// 输出 true
}
上述结果表明 当我们在进行浅克隆的时候 如果这个对象 存在对其他对象的引用,那么克隆后的引用值,和原对象的引用是一样的,如下图所示
3、深克隆: 顾名思义 跟浅克隆相比的区别是 克隆后的对象的对其他对象引用与原对象不同。
实现方式:
package com.wcly.activemqTest;
public class Student implements Cloneable {
private String classNo;
private String teacherName ;
public String getTeacherName() {
return teacherName;
}
public void setTeacherName(String teacherName) {
this.teacherName = teacherName;
}
public String getClassNo() {
return classNo;
}
public void setClassNo(String classNo) {
this.classNo = classNo;
}
public Student(String classNo, String teacherName) {
this.classNo = classNo;
this.teacherName = teacherName;
}
@Override
public Object clone() throws CloneNotSupportedException {
Student stu = null;
try {
stu = (Student) super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return stu ;
}
}
@Override
public Object clone() throws CloneNotSupportedException {
People p = null;
try {
p = (People) super.clone();
p.stu = (Student)stu.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return p ;
}
接下来 我们看下测试代码:
@Test
public void test3()throws CloneNotSupportedException{
People p1 = new People("1","zhang3",12,new Student("1","teacher"));
People p2 = (People) p1.clone();
System.out.println(p1==p2);// 输出 false
p1.setUsername("li4");
System.out.println(p2.getUsername()); // 输出 zhang3
p1.getStu().setClassNo("2");
System.out.println(p2.getStu().getClassNo()); // 输出 1
System.out.println(p1.getStu()==p2.getStu());// 输出 false
}