为什么使用对象拷贝(克隆)
当一个对象不够用的时候,如页面要分别显示老师和学生的信息,我们可以先new一个老师teacher对象,然后使用对象拷贝或者克隆的方式创建一个学生student对象。
//伪代码
Person teacher = new Person("张三老师","男","xxx学院");
Person student = CopyfromPerson(teacher);
student.setName("李四学生");
在上面的例子中,张三老师和李四学生就是名字不一样,其它的两个字段可以一样,所以我们可以拷贝 teacher对象创建student对象。
如何实现对象拷贝(克隆Cloneable接口)
1) 实现Cloneable接口的浅拷贝,浅拷贝中的类只包含基本数据类型。
定义一个简单的Person类,并实现克隆接口Cloneable。
class Person implements Cloneable{
private String name ;
private String sex;
private String college;
/**
* 浅拷贝或者浅克隆
* @return
*/
@Override
public Object clone() {
Person person = null;
try{
person = (Person) super.clone();
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}
return person;
}
public Person() {
}
public Person(String name, String sex, String college) {
this.name = name;
this.sex = sex;
this.college = college;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getCollege() {
return college;
}
public void setCollege(String college) {
this.college = college;
}
}
调用拷贝方法。
public class CloneExample {
public static void main(String[] args) {
Person teacher = new Person("张三老师","男","xxx学院");
Person student = (Person) teacher.clone();//浅拷贝
System.out.println(teacher);
System.out.println(student);
}
}
从输出结果中我们看到teacher和student对象的地址不一样。
这里的clone对象相当于完全复制了一个新的对象,新的对象有它自己的地址,修改原来的对象新对象不变。不过这里是浅拷贝,只拷贝的对象第一层属性。对于有多层级的对象(深拷贝),该方法就不成立了,下面看clone的深拷贝。
2) 实现Cloneable接口的深拷贝,深拷贝中的类包含非基本数据类型。
这里给Person类增加一个Address类,如下:
class Address implements Cloneable{
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Person implements Cloneable{
private String name ;
private String sex;
private String college;
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
/**
* 深拷贝
* @return
*/
@Override
public Object clone() {
Person person = null;
try{
person = (Person) super.clone();
person.address = (Address) address.clone();
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}
return person;
}
public Person() {
}
public Person(String name, String sex, String college) {
this.name = name;
this.sex = sex;
this.college = college;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getCollege() {
return college;
}
public void setCollege(String college) {
this.college = college;
}
}
调用拷贝方法
public class CopyExample2{
public static void main(String[] args) {
Person teacher = new Person("张三老师","男","xxx学院");
Address address = new Address();
address.setAddress("湖北 武汉");
teacher.setAddress(address);
Person student = (Person) teacher.clone();//浅拷贝
System.out.println(teacher);
System.out.println(student);
}
}
深拷贝和浅拷贝区别是什么
他们的区别就是实现Cloneable接口的类中是否包含其他的类。
- 实现Cloneable接口的类中只包含基本数据类型则是浅拷贝
- 实现Cloneable接口的类中包含非基本数据类型则是深拷贝
说的再直白点就是浅拷贝只拷贝对象的第一层属性,深拷贝拷贝对象的多层属性。