美文网首页
Java Clone 学习

Java Clone 学习

作者: ObadiObada | 来源:发表于2017-12-19 15:04 被阅读0次

Java Clone 学习

原文地址:详解Java中的clone方法

通常在Java中我们通过new关键字创建对象,代码如下:

Human human = new Human();
Human human2 = human;
System.out.println("human is :" + human);
System.out.println("human2 is :" + human2);

打印如下:

human is :TestClone$Human@6d06d69c

human2 is :TestClone$Human@6d06d69c

从结果看出human2和human指向了同一对象,从这行代码页印证了引用即是Java种的指针这一说法。

Java中创建对象的方法有很多,常见的有:

  • new 使用new关键字首先为新对象创建内存,然后使用构造函数为新对象的各个Field初始化
  • clone 首先为新对象创建内存,然后使用旧的对象的值填充新的对象的各个Field
  • readobject 首先为新对象创建内存,从流中读取数据,并填充新对象的各个Field

Clone 方法

Clone 定义在Object类中的保护方法,一个类如果要支持Clone,需要按照下面的两个步骤编写代码。

  • 重写Clone方法
  • 实现Cloneable接口 - Cloneable是一个标记接口,实现这个接口只需要在顶一类是声明即可,如果类未实现Cloneable接口,调用其Clone方法会抛出CloneNotSupportedException

一个例子:

static class Human implements Cloneable {
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

public static void main(String[] args) {
    Human human1 = new Human();
    System.out.println("human is :" + human1);
    try {
        Human human2 = (Human) human1.clone();
        System.out.println("human2 is :" + human2);
    } catch (CloneNotSupportedException e) {
        System.out.println("human CloneNotSupportedException");
    }
}

运行结果为:

human is :TestClone$Human@6d06d69c

human2 is :TestClone$Human@7852e922

从运行结果看,Clone方法创建了新的对象。

深复制和浅复制

浅复制

浅复制是指为新的对象创建内存,并使用旧的对象的中的引用的值填充新的对象中引用的值,观察如下代码:

static class Human implements Cloneable {
    public Head mHead;

    public Human(Head head) {
        mHead = head;
    }

    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

public static void main(String[] args) {
    Human human1 = new Human(new Head());
    try {
        Human human2 = (Human) human1.clone();
        System.out.println("human1 is :" + human1);
        System.out.println("human2 is :" + human2);
        System.out.println("human1 head is :" + human1.mHead);
        System.out.println("human2 head is :" + human2.mHead);
    } catch (CloneNotSupportedException e) {
        System.out.println("human CloneNotSupportedException");
    }
}

运行结果:

human1 is :TestClone$Human@6d06d69c
human2 is :TestClone$Human@7852e922
human1 head is :TestClone$Head@4e25154f
human2 head is :TestClone$Head@4e25154f

从运行结果看,Object类中Clone方法的实现为浅复制

深复制

深复制是指,为新的对象申请内存,并未其中的每个引用申请内存。将上述的代码改造如下:

static class Head implements Cloneable {
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

static class Human implements Cloneable {
    public Head mHead;

    public Human(Head head) {
        mHead = head;
    }

    public Object clone() throws CloneNotSupportedException {
        Human human = (Human) super.clone();
        human.mHead = (Head) mHead.clone();
        return human;
    }
}

public static void main(String[] args) {
    Human human1 = new Human(new Head());
    try {
        Human human2 = (Human) human1.clone();
        System.out.println("human1 is :" + human1);
        System.out.println("human2 is :" + human2);
        System.out.println("human1 head is :" + human1.mHead);
        System.out.println("human2 head is :" + human2.mHead);
    } catch (CloneNotSupportedException e) {
        System.out.println("human CloneNotSupportedException");
    }

}

结果如下:

human1 is :TestClone$Human@6d06d69c
human2 is :TestClone$Human@7852e922
human1 head is :TestClone$Head@4e25154f
human2 head is :TestClone$Head@70dea4e

从结果看human和head都指向了新的对象(内存)。

继续改造上述代码:

static class Face {

}

static class Head implements Cloneable {
    Face mFace;

    public Head() {
        mFace = new Face();
    }

    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

static class Human implements Cloneable {
    public Head mHead;

    public Human(Head head) {
        mHead = head;
    }

    public Object clone() throws CloneNotSupportedException {
        Human human = (Human) super.clone();
        human.mHead = (Head) mHead.clone();
        return human;
    }
}

public static void main(String[] args) {
    Human human1 = new Human(new Head());
    try {
        Human human2 = (Human) human1.clone();
        System.out.println("human1 is :" + human1);
        System.out.println("human2 is :" + human2);
        System.out.println("human1 head is :" + human1.mHead);
        System.out.println("human2 head is :" + human2.mHead);
        System.out.println("human1 face is :" + human1.mHead.mFace);
        System.out.println("human2 face is :" + human2.mHead.mFace);
    } catch (CloneNotSupportedException e) {
        System.out.println("human CloneNotSupportedException");
    }
}

运行结果如下:

human1 is :TestClone$Human@6d06d69c
human2 is :TestClone$Human@7852e922
human1 head is :TestClone$Head@4e25154f
human2 head is :TestClone$Head@70dea4e
human1 face is :TestClone$Face@5c647e05
human2 face is :TestClone$Face@5c647e05
从结果看face又指向了相同对象(引用),为了完成彻底的深复制,需要对Face类和Head类做如下改造:

static class Face implements Cloneable {
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

static class Head implements Cloneable {
    Face mFace;

    public Head() {
        mFace = new Face();
    }

    protected Object clone() throws CloneNotSupportedException {
        Head head = (Head) super.clone();
        head.mFace = (Face) mFace.clone();
        return head;
    }
}

结果如下:

human1 is :TestClone$Human@6d06d69c
human2 is :TestClone$Human@7852e922
human1 head is :TestClone$Head@4e25154f
human2 head is :TestClone$Head@70dea4e
human1 face is :TestClone$Face@5c647e05
human2 face is :TestClone$Face@33909752

结论

  1. Object类提供了Clone方法用于复制对象,
  2. 一个类如果要支持Clone,需要重写Clone方法,并实现Cloneable接口
  3. Object类的Clone实现为浅复制
  4. 为了达到深复制,对象的引用,以及其引用的引用(依次类推)都需要实现深复制

相关文章

  • Java Clone 学习

    Java Clone 学习 原文地址:详解Java中的clone方法 通常在Java中我们通过new关键字创建对象...

  • Java Clone

    Java Clone 平时项目中用的也不多,今天来实践下Java的Clone。Clone主要分为“浅拷贝”与“深拷...

  • Java Clone

    Java深复制与浅复制 https://blog.csdn.net/accp_fangjian/article/d...

  • 详解Java中的clone方法 -- 深拷贝和浅拷贝

    Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象。...

  • Prototype模式(设计模式)

    clone方法和java.lang.Clonable接口 Product.java Manager.java Me...

  • 第11条:谨慎地覆盖clone

    clone 方法使用详解 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对...

  • java - 014 - clone

    java对象的复制 1.实现Cloneable协议

  • Clone() method in Java

    原文:geeks4geeks Java 中的 clone() 方法 对象 clone 是指创建对象的精确拷贝,它创...

  • java clone问题

    在java中,如果需要有拷贝问题,都会使用到父类Object的Clone方法,能够为我们提供对象的拷贝方法,在使用...

  • 原型模式——对象clone

    Java中对象的clone可以通过Object中的clone()来实现,步骤如下:1、实现cloneable接口(...

网友评论

      本文标题:Java Clone 学习

      本文链接:https://www.haomeiwen.com/subject/zzobwxtx.html