在JAVA中对象的克隆有的时候是必要的,克隆分两种:浅克隆、深克隆。
浅克隆 指如果对象中含有非基本类型的成员,那么克隆的对象与源对象共用该成员的引用,即在两个对象中该成员的引用是一样的。这种克隆是相对意义上的克隆,克隆的对象与源对象并没有绝对的独立。
深克隆 指克隆的对象与源对象在所有的成员上都有不同引用,实现了绝对意义上的克隆。浅克隆比起深克隆来很容易实现。下面先说浅克隆。
浅克隆的实现 :待克隆的类需实现java.lang.Cloneable接口,该接口无待实现的方法,只是一种标记。然后覆盖Object类的clone()方法,在方法中调用Object的clone()方法即可。
深 克隆的实现 :把此方法放到要克隆的对象中,并使被克隆的对象以及引用到的对象实现java.io.Serializable接口。
public Object clone() throws CloneNotSupportedException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(bos);
} catch (IOException e) {
e.printStackTrace();
}
try {
oos.writeObject(this);
} catch (IOException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
// 将流序列化成对象
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(bis);
} catch (IOException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
try {
return ois.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
return null;
// return super.clone();
}
深克隆例子 :
package com.javaeye.xiaobian;
import java.io.Serializable;
public class Teacher implements Serializable {
public int age;
public String name;
private Result result;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Result getResult() {
return result;
}
public void setResult(Result result) {
this.result = result;
}
}
package com.javaeye.xiaobian;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Student implements Cloneable, Serializable {
public int age;
public String name;
public Teacher teacher;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public Object clone() throws CloneNotSupportedException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(bos);
} catch (IOException e) {
e.printStackTrace();
}
try {
oos.writeObject(this);
} catch (IOException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
// 将流序列化成对象
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(bis);
} catch (IOException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
try {
return ois.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
return null;
// return super.clone();
}
}
package com.javaeye.xiaobian;
import java.io.Serializable;
public class Result implements Serializable {
private long numeric = 100;
public long getNumeric() {
return numeric;
}
public void setNumeric(long numeric) {
this.numeric = numeric;
}
package com.javaeye.xiaobian;
public class Test {
/**
* @param args
* @throws CloneNotSupportedException
*/
public static void main(String[] args) throws CloneNotSupportedException {
// TODO Auto-generated method stub
Result result = new Result();
result.setNumeric(101);
Teacher teacher = new Teacher();
teacher.setAge(26);
teacher.setName("xiaobian.iteye.com");
teacher.setResult(result);
Object c;
Student student = new Student();
student.setAge(20);
student.setName("xiaobian.iteye.com");
student.setTeacher(teacher);
Student student1 = (Student) student.clone();
// 克隆后未修改引用数据之前
System.out.println(student.getTeacher().getResult().getNumeric());
System.out.println(student1.getTeacher().getResult().getNumeric());
// 克隆后修改引用数据之后
student1.getTeacher().getResult().setNumeric(100);
System.out.println(student.getTeacher().getResult().getNumeric());
System.out.println(student1.getTeacher().getResult().getNumeric());
}
}
}
测试输入出的结果:
101
101
101
100
浅克隆的例子 :
package com.javaeye.xiaobian;
public class Student implements Cloneable {
public int age;
public String name;
public Teacher teacher;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
package com.javaeye.xiaobian;
public class Teacher {
public int age;
public String name;
private Result result;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Result getResult() {
return result;
}
public void setResult(Result result) {
this.result = result;
}
}
package com.javaeye.xiaobian;
public class Result {
private long numeric = 100;
public long getNumeric() {
return numeric;
}
public void setNumeric(long numeric) {
this.numeric = numeric;
}
}
package com.javaeye.xiaobian;
public class Test {
/**
* @param args
* @throws CloneNotSupportedException
*/
public static void main(String[] args) throws CloneNotSupportedException {
// TODO Auto-generated method stub
Result result = new Result();
result.setNumeric(101);
Teacher teacher = new Teacher();
teacher.setAge(26);
teacher.setName("xiaobian.iteye.com");
teacher.setResult(result);
Student student = new Student();
student.setAge(20);
student.setName("xiaobian.iteye.com");
student.setTeacher(teacher);
Student student1 = (Student) student.clone();
// 克隆后未修改引用数据之前
System.out.println(student.getTeacher().getResult().getNumeric());
System.out.println(student1.getTeacher().getResult().getNumeric());
// 克隆后修改引用数据之后
student1.getTeacher().getResult().setNumeric(100);
System.out.println(student.getTeacher().getResult().getNumeric());
System.out.println(student1.getTeacher().getResult().getNumeric());
}
}
测试结果:
101
101
100
100