浅克隆与深克隆
浅克隆:
public class Person implements Cloneable {
private String name;
private int age;
private Teacher teacher;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public Person clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone();
return cloned;
}
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 Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Override
public String toString() {
return "name:\t" + name + "\tage:\t" + age+teacher;
}
}
public class Teacher {
private String name;
private int age;
public Teacher(String name, int age) {
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;
}
@Override
public String toString() {
return "\tteachername:\t" + name + "\tteacherage:\t" + age;
}
}
public class CloneTest {
/**
* 对象的克隆
对象的浅克隆:
对象浅克隆要注意的细节:
1. 如果一个对象需要调用clone的方法克隆,那么该对象所属的类必须要实现Cloneable接口。
2. Cloneable接口只不过是一个标识接口而已,没有任何方法。
3. 对象的浅克隆就是克隆一个对象的时候,如果被克隆的对象中维护了另外一个类的对象,这时候只是克隆另外一个对象的地址,而没有把
另外一个对象也克隆一份。
4. 对象的浅克隆也不会调用到构造方法的。
* @param args
*/
public static void main(String[] args) {
Person p1= new Person("小明", 23);
Teacher t1= new Teacher("李老师",45);
p1.setTeacher(t1);
System.out.println(p1);
try {
Person p2 = (Person) p1.clone();
System.out.println(p2.getTeacher().equals(p1.getTeacher()));
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
输出:
name: 小明 age: 23 teachername: 李老师 teacherage: 45
true
深克隆需要对克隆对象里对其他对象的引用也克隆,对象都要事先Cloneable接口,全部对象都克隆一份
public class Person implements Cloneable {
private String name;
private int age;
private Teacher teacher;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public Person clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone();
cloned.teacher=teacher.clone();
return cloned;
}
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 Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Override
public String toString() {
return "name:\t" + name + "\tage:\t" + age+teacher;
}
}
public class Teacher implements Cloneable {
private String name;
private int age;
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public Teacher clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return (Teacher) super.clone();
}
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 "\tteachername:\t" + name + "\tteacherage:\t" + age;
}
}
public class DeepClone {
public static void main(String[] args) {
Person p1= new Person("小明", 23);
Teacher t1= new Teacher("李老师",45);
p1.setTeacher(t1);
System.out.println(p1);
try {
Person p2 = p1.clone();
p2.setName("小华");
System.out.println(p2.getTeacher().equals(p1.getTeacher()));
System.out.println(p2);
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
输出:
name: 小明 age: 23 teachername: 李老师 teacherage: 45
false
name: 小华 age: 23 teachername: 李老师 teacherage: 45
另外一种深克隆方法:将要克隆的对象实现序列化接口Serializable
public class Person implements Cloneable,Serializable {
private String name;
private int age;
private Teacher teacher;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name, int age, Teacher teacher) {
this.name = name;
this.age = age;
this.teacher = teacher;
}
@Override
public Person clone() throws CloneNotSupportedException {
return (Person) super.clone();
}
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 Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Override
public String toString() {
return "name:\t" + name + "\tage:\t" + age+teacher;
}
}
public class Teacher implements Serializable {
private String name;
private int age;
public Teacher(String name, int age) {
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;
}
@Override
public String toString() {
return "\tteachername:\t" + name + "\tteacherage:\t" + age;
}
}
public class DeepClone {
/*
对象的深克隆: 对象的深克隆就是利用对象的输入输出流把对象先写到文件上,然后再读取对象的
信息这个过程就称作为对象的深克隆。
ObjectInputStream
ObjectOutputStream
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
Person p1= new Person("小明", 23);
Teacher t1= new Teacher("李老师",45);
p1.setTeacher(t1);
writeObj(p1);
Person p2=readObj();
System.out.println(p1);
System.out.println(p2+"\tp1.eauals(p2)\t"+p2.equals(p1));
System.out.println(p1.getTeacher().equals(p2));
}
public static Person readObj() throws ClassNotFoundException,IOException{
FileInputStream fis = new FileInputStream("F:\\obj.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Person p = (Person) ois.readObject();
return p;
}
public static void writeObj(Person p) throws IOException{
FileOutputStream fos = new FileOutputStream("F:\\obj.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(p);
oos.close();
}
}
输出:
name: 小明 age: 23 teachername: 李老师 teacherage: 45
name: 小明 age: 23 teachername: 李老师 teacherage: 45 p1.eauals(p2) false
false