浅克隆:指在克隆一个对象的时候,如果被克隆的对象中又维护了另一个对象,这个时候虽然克隆了成功了,但是仅仅是对另一个对象的地址克隆了,并没有将另一个对象也克隆了;
深克隆:采用IO流来实现,使用 ObjectOutputStream 将对象写入文件中,然后再用ObjectInputStream读取回来
浅克隆程序如下:
public class MyTest {
public static void main(String[] args) throws CloneNotSupportedException {
Flower flower = new Flower();
Dirt dirt = new Dirt();
flower.dirt = dirt;
flower.name = "百合花";
flower.color = "黄色";
flower.dirt.name = "黑土地";
System.out.println(flower);//克隆之前,flower对象,以及维护的对象;
Object clone = flower.clone();//复制对象;
Flower flower1 = (Flower) clone;//因为复制出来的clone对象时Object顶级父类,所以需要向下转型;
flower1.dirt.name="红土地";
System.out.println(flower);//打印的还是克隆之前,对象的变量值,以及其维护对象的变量值;
System.out.println(flower1);//打印的是克隆之后,对象的变量值,以及所维护对象的变量值;
}
}
class Flower implements Cloneable {//cloneable 仅仅是个标记,是告诉JVM支持克隆的接口,里面没有任何抽象方法;
String name;
String color;
Dirt dirt;//维护的对象;
public Flower() {
}
public Flower(String name, String color, Dirt dirt) {
this.name = name;
this.color = color;
this.dirt = dirt;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Flower{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
", dirt=" + dirt +
'}';
}
}
class Dirt {
String name;
public Dirt() {
}
public Dirt(String name) {
this.name = name;
}
@Override
public String toString() {
return "Dirt{" +
"name='" + name + '\'' +
'}';
}
}
深克隆代码示例如下:
深克隆先要将对象,以及其所维护的对象,通过序列化流输出到文本文档中存储起来,完成整体克隆;
public class Clone {
public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
Flower flower = new Flower();
Dirt dirt = new Dirt();
flower.dirt = dirt;
flower.name = "百合花";
flower.color = "黄色";
flower.dirt.name = "黑土地";
System.out.println(flower);//克隆之前,flower对象,以及维护的对象;
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("flower.txt"));
oos.writeObject(flower);
oos.close();
}
}
class Flower implements Cloneable, Serializable {//cloneable 仅仅是个标记,是告诉JVM支持克隆的接口,里面没有任何抽象方法;
String name;
String color;
Dirt dirt;//维护了Dirt对象;
public Flower() {
}
public Flower(String name, String color, Dirt dirt) {
this.name = name;
this.color = color;
this.dirt = dirt;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Flower{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
", dirt=" + dirt +
'}';
}
}
class Dirt implements Serializable{
String name;
public Dirt() {
}
public Dirt(String name) {
this.name = name;
}
@Override
public String toString() {
return "Dirt{" +
"name='" + name + '\'' +
'}';
}
}
其次要想读取克隆出来的对象,用反序列化流再关联文件读取出来;
public class Clone {
public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
//反序列化输入流关联文件,读取复制出来的文本文件,完成深克隆
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("flower.txt"));
Object obj = ois.readObject();
Flower flower= (Flower) obj;
System.out.println(flower.name+"\t"+flower.color+"\t"+flower.dirt.name);
}
}
class Flower implements Cloneable, Serializable {//cloneable 仅仅是个标记,是告诉JVM支持克隆的接口,里面没有任何抽象方法;
String name;
String color;
Dirt dirt;//维护了Dirt对象;
public Flower() {
}
public Flower(String name, String color, Dirt dirt) {
this.name = name;
this.color = color;
this.dirt = dirt;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Flower{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
", dirt=" + dirt +
'}';
}
}
class Dirt implements Serializable{
String name;
public Dirt() {
}
public Dirt(String name) {
this.name = name;
}
@Override
public String toString() {
return "Dirt{" +
"name='" + name + '\'' +
'}';
}
}