Java 深、浅克隆

克隆的实现

对象实现Cloneable接口,并实现clone方法

克隆的优点

克隆相对于new一个新对象的时间开销要少,因为clone出的对象不会执行对象的Construstorf方法。这样就节省了一些时间。这是Java 代码优化的一个点。

我们看下代码证明下:

public class Man implements Cloneable{

    public Man() {
        System.out.println("Man constructor");
    }

    private Head head;

    public Head getHead() {
        return head;
    }

    public void setHead(Head head) {
        this.head = head;
    }

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

Main测试

 public static void main(String[] args) throws CloneNotSupportedException {
        Man man = new Man();
        Head head = new Head();
        man.setHead(head);
        Man clone = (Man)man.clone();
    }

输出结果为

Man constructor

深克隆、浅克隆

我们知道一个对象成员变量有两种类型,一个是基础类型,一个是引用类型。基础类型的数据是存储在栈中的,引用类型的数据是存储在堆中。浅克隆代表的意义是克隆出来的对象的引用类型的成员变量和源对象的成员变量其实指向的是同一个堆对象,即他们equals判断为true.
那我们要如何实现深克隆呢,这就需要我们再引用类型的成员变量的对象中也要实现Cloneable接口,重写clone方法。同时在父对象的clone 方法中 给与成员变量赋值为clone出来的对象,具体看代码

public class Head implements Cloneable{
    private Face face;

    public Face getFace() {
        return face;
    }

    public void setFace(Face face) {
        this.face = face;
    }

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

public class Man implements Cloneable{

    public Man() {
        System.out.println("Man constructor");
    }

    private Head head;

    public Head getHead() {
        return head;
    }

    public void setHead(Head head) {
        this.head = head;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        Man man = (Man)super.clone();
        head = (Head)head.clone();
        return man;
    }
}

测试代码

 public static void main(String[] args) throws CloneNotSupportedException {
        Man man = new Man();
        Head head = new Head();
        man.setHead(head);
        Man clone = (Man)man.clone();

        System.out.println("man 是否是同一个对新"+man.equals(clone));

        System.out.println("man.head 是否是同一个引用"+man.getHead().equals(clone.getHead()));

    }

结果为:

Man constructor
man 是否是同一个对新false
man.head 是否是同一个引用false

但是我们如果要完全实现深克隆的成本实际是比较高的。因为对象的成员变量的成员变量的成员变量的成员变量。。。。 无线下去,需要所有的成员变量都实现Cloneable,实现clone。并且在父对象都要在clone中设置 xx= xx.clone()

贴个别人博客的图:

时间: 2024-09-18 02:47:26

Java 深、浅克隆的相关文章

理解java中的深复制和浅复制_java

 Java语言的一个优点就是取消了指针的概念,但也导致了许多程序员在编程中常常忽略了对象与引用的区别,本文会试图澄清这一概念.并且由于Java不能通过简单的赋值来解决对象复制的问题,在开发过程中,也常常要要应用clone()方法来复制对象.本文会让你了解什么是影子clone与深度clone,认识它们的区别.优点及缺点.       看到这个标题,是不是有点困惑:Java语言明确说明取消了指针,因为指针往往是在带来方便的同时也是导致代码不安全的根源,同时也会使程序的变得非常复杂难以理解,滥用指针写

IBM中国研发中心面试题,如何用Java写一个程序达到对象深浅克隆的效果?不能用API

问题描述 IBM中国研发中心面试题,如何用Java写一个程序达到对象深浅克隆的效果?不能用API.来吧,大家发表意见,全分奉上. 问题补充:没人知道吗,能不能告诉我啊 解决方案 import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;/** * 深/浅克隆 * * @auth

【北京】 JAVA 大神们,也有和我一样北漂的吗?

问题描述 来到北京,心态"异常"的崩溃.IT行业!人才济济!JAVA后台能人!在家待业!知音们!顶起来! 解决方案 解决方案二:我顶,中国人口众多,我们只是混口饭吃解决方案三:顶!!!顶!!!顶!!!解决方案四:32个赞解决方案五:我顶,中国人口众多,我们只是混口饭吃解决方案六:我顶,中国人口众多,我们只是混口饭吃出门小心雾霾呀解决方案七: 解决方案八:北京java需求依然很大,同时刚去,我年后去解决方案九:能人快去为祖国做贡献啊待业干啥解决方案十:一入Java深似海,从此女友是路人解

Java中对象的深复制(深克隆)和浅复制(浅克隆)介绍_java

1.浅复制与深复制概念 ⑴浅复制(浅克隆)      被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复制(深克隆)      被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量.那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象.换言之,深复制把要复制的对象所引用的对象都复制了一遍. 2.Java的clone()方法 ⑴clone方法将

java 浅复制和深复制

原文:http://ttitfly.iteye.com/blog/155422 1.java里的clone分为:  A:浅复制(浅克隆): 浅复制仅仅复制所考虑的对象,而不复制它所引用的对象.  b:深复制(深克隆):深复制把要复制的对象所引用的对象都复制了一遍.  Java中对象的克隆,为了获取对象的一份拷贝,我们可以利用Object类的clone()方法.必须要遵循下面三点  1.在派生类中覆盖基类的clone()方法,并声明为public[Object类中的clone()方法为protec

Java中对象的深复制和浅复制详解

1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复制(深克隆) 被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量.那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象.换言之,深复制把要复制的对象所引用的对象都复制了一遍. 2.Java的clone()方法 ⑴clone方法将对象复制了一份并返回

Java中的深克隆和浅克隆——Cloneable接口

一.没有使用克隆带来的问题 public class CloneTest {static Student s = new Student("aaa", 20); // 直接赋值带来的问题public static void noclone(){// 传的是引用的副本,改变了noCloneStudent也改变了sStudent noCloneStudent = new Student();noCloneStudent = s;noCloneStudent.setName("bb

android 浅复制和深复制-Java Generic Deep Copy 篇

关于Java Generic Deep Copy 在java中的应用和注意事项,请参考:http://blog.csdn.net/yang_hui1986527/article/details/7039425 而关于在android程序中通过clone方法来进行浅复制和深复制,请参考:http://blog.csdn.net/yang_hui1986527/article/details/7036818 众所周知,android上层使用的是java语言,因此理论上于Java Generic De

Java Web开发过程中隐藏很深的问题

Java Web开发过程中隐藏很深的问题 (1)企业状态不对 企业的状态由订单状态决定,但是同一个应用,一个企业可以有多个订单, 那么在有多个订单的情况下,企业的状态由那个订单决定呢? 答:由 最新的订单决定. 但是代码逻辑不对:   应该使用有序的for循环:     (2)org.json.JSONObject的getString 方法可能抛出异常 Java代码   //记录分享人               String sharer=appInfoObject.getString("sh