为什么要对象克隆
1,克隆的对象包含修改属性
2,速度快
如何实现克隆
方法1
被复制的类需要实现Clonenable接口
覆盖clone()方法,方法中调用super.clone()方法得到需要的复制对象
package tmp_project;
public class Student implements Cloneable {
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 Address getAdd() {
return add;
}
public void setAdd(Address add) {
this.add = add;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", add=" + add + "]";
}
private String name;
private int age;
private Address add;
@Override
protected Object clone() throws CloneNotSupportedException {
Student stu = (Student) super.clone(); // 浅复制
stu.add = (Address) add.clone(); // 深度复制
return stu;
}
public static void main(String[] args) throws Exception {
Address ad = new Address();
ad.setAddr("北京");
Student s1 = new Student();
s1.setAdd(ad);
Student s2 = (Student) s1.clone();
s2.getAdd().setAddr("上海");
System.out.println("S1:" + s1.toString());
System.out.println("S2:" + s2.toString());
}
}
class Address implements Cloneable {
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
private String addr;
@Override
public String toString() {
return "Address [addr=" + addr + "]";
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
}
方式2
实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。
package tmp_project;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Student2 implements Serializable {
private static final long serialVersionUID = 1270778495979937539L;
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;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", add=" + add + "]";
}
public Address2 getAdd() {
return add;
}
public void setAdd(Address2 add) {
this.add = add;
}
private String name;
private int age;
private Address2 add;
public Student2 myclone() {
Student2 stu = null;
try { // 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
// 将流序列化成对象
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
stu = (Student2) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return stu;
}
public static void main(String[] args) throws Exception {
Address2 ad = new Address2();
ad.setAddr("北京");
Student2 s1 = new Student2();
s1.setAdd(ad);
Student2 s2 = s1.myclone();
s2.getAdd().setAddr("上海");
System.out.println("S1:" + s1.toString());
System.out.println("S2:" + s2.toString());
}
}
class Address2 implements Serializable {
private static final long serialVersionUID = -2301486731388709759L;
private String addr;
@Override
public String toString() {
return "Address [addr=" + addr + "]";
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
}