`
pengcqu
  • 浏览: 774166 次
  • 性别: Icon_minigender_1
  • 来自: 未来
社区版块
存档分类
最新评论

Java中对Clone的理解

阅读更多

  面试中经常遇到Clone的相关知识,今天总算是把Clone理解的比较透彻了!Java中Clone的概念大家应该都很熟悉了,它可以让我们很方便的“制造”出一个对象的副本来,下面来具体看看java中的Clone机制是如何工作的?
     1. Clone和Copy
     假设现在有一个User对象,User u1=new User(“U1001”,“Jason”,25),通
常我们会有这样的赋值User u2=u1,这个时候只是简单了copy了一下reference,u2和u1都指向内存中同一个object,这样u2或者u1的一个操作都可能影响到对方。打个比方,如果我们通过u2.setAge()方法改变了Age域的值,那么u1通过getAge()方法得到的就是修改之后的Age域的值,显然这不是我们愿意看到的。我们希望得到u1的一个精确拷贝,同时两者互不影响,这时候我们就可以使用Clone来满足我们的需求。User u2=u1.clone(),这时会生成一个新的User对象,并且和u1具有相同的属性值和方法。

      2. Shallow Clone和Deep Clone
Clone是如何完成的呢?Object在对某个对象实施Clone时对其是一无所知的,它仅仅是简单地执行域对域的copy,这就是Shallow Clone。这样,问题就来了咯,以User为例,它里面有一个域birthday不是基本型别的变量,而是一个reference变量,经过Clone之后就会产生一个新的Date型别的reference,它和原始对象中对应的域指向同一个Date对象,这样克隆类就和原始类共享了一部分信息,而这样显然是不利的,过程下图所示:

 


这个时候我们就需要进行deep Clone了,对那些非基本型别的域进行特殊的处理,例如本例中的birthday。我们可以重新定义Clone方法,对birthday做特殊处理,如下代码所示:

class User implements Cloneable
{
     public Object clone() throws CloneNotSupportedException
     {
       User cloned = User super.clone();
       cloned.birthday = (Date) hireDay.clone()
       return cloned;
     }
}

 

3. Clone()方法的保护机制在Object中Clone()是被申明为protected的,这样做是有一定的道理的,以User类为例,通过申明为protected,就可以保证只有User类里面才能“克隆”User对象,原理可以参考我前面关于public、protected、private的学习笔记。

4. Clone()方法的使用Clone()方法的使用比较简单,注意如下几点即可:a. 什么时候使用shallow Clone,什么时候使用deep Clone,这个主要看具体对象的域是什么性质的,基本型别还是reference variableb. 调用Clone()方法的对象所属的类(Class)必须implements Clonable接口,否则在调用Clone方法的时候会抛出CloneNotSupportedException。

 

理解有误之处,还望高 手 指 点!

 

 

相关链接:

★  Java知识点汇总 

全球软件项目外包平台 兼职做外包 挣Money!

 

 

 

 
14
2
分享到:
评论
6 楼 鬼脚七 2011-09-23  
深度克隆可以通过序列化搞定
5 楼 t414789324 2009-10-20  
。。。 菜鸟学习了
4 楼 myloveiscomealone 2009-10-19  
不好意思,贴得有点乱了!
3 楼 myloveiscomealone 2009-10-19  
给你一个深度的,不过这也不深,还可以克到五段,六段!
package com.colorme.t20.deepclone;
/**
* 被克隆对象里包含的引用类
* @author 王经纬
* @version 2008-8-29
*/

public class ReferencedObject implements Cloneable{
    private int i = 0;
    public ReferencedObject(int i) {
        this.i = i;
    }
    public void doubleValue(){
        this.i = 2*this.i;
    }
  
    public int getNumber(){
        return this.i;
    }

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

package com.feixun.t20.deepclone;

/**
* 带引用的克隆
* @author 王经纬
* @version 2008-8-29
*/
public class ObjectForDeepClone  implements Cloneable{
    private int i = 0;
    private ReferencedObject rf = null;
  
    public void setNum(int i) {
        this.i = i;
    }
  
    public void setReferencedObject(ReferencedObject rf){
        this.rf = rf;
    }
      
    public int getNumber(){
        return this.i;
    }
  
    public ReferencedObject getReferencedObject(){
        return this.rf;
    }
  
    // 重写Object的clone
    public Object clone() throws CloneNotSupportedException {
    ObjectForDeepClone cloneObject=(ObjectForDeepClone)super.clone();
    // 调用引用对象的clone方法
        if(rf!=null){
            ReferencedObject rfClone = (ReferencedObject)rf.clone();
            cloneObject.setReferencedObject(rfClone);
        }

         return cloneObject;
     }
}  

package com.feixun.t20.deepclone;

import java.io.Serializable;

public class CloneTest {

    public static void main(String[] args) {
        ObjectForDeepClone ofsc = new ObjectForDeepClone();
        ofsc.setNum(888);
        ofsc.setReferencedObject(new ReferencedObject(1));
       
        // 开始clone了!
        ObjectForDeepClone deepCloneObject = null;
        try {
            deepCloneObject = (ObjectForDeepClone) ofsc.clone();
        } catch (CloneNotSupportedException ex) {
            System.out.println("Sorry,Clone Not Supported!");
        }

        // 测试clone是否成功
        if(deepCloneObject!=null){
            System.out.println("before clone");
            System.out.println("ObjectForShallowClone get number : " + ofsc.getNumber());
            System.out.println("ObjectForShallowClone ReferencedObject get number : "+ofsc.getReferencedObject().getNumber()+"\n");
          
            deepCloneObject.setNum(999);
            deepCloneObject.getReferencedObject().doubleValue();

            System.out.println("after clone");
            System.out.println("CloneObject get number : " + deepCloneObject.getNumber());
            System.out.println("CloneObject ReferencedObject get number : " + deepCloneObject.getReferencedObject().getNumber());
           
            System.out.println();
            System.out.println("ObjectForShallowClone get number : " + ofsc.getNumber());
            System.out.println("ObjectForShallowClone ReferencedObject get number : " + ofsc.getReferencedObject().getNumber());
        }      
    }
}



2 楼 pengcqu 2009-10-19  
myloveiscomealone 写道
分析得还可以,有深度克隆有浅克隆。
我给你补充一点!
package com.model.t22.simple;

public class Student implements Cloneable{
private int age;
private String name;
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 Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
package com.model.t22.simple;

public class SimpleTest {
public static void main(String[] args) {
Student s = new Student();
s.setAge(30);
s.setName("zhangsan");

System.out.println("克隆之前的原始对象年龄值是:"+s.getAge());
System.out.println("克隆之前的原始对象名字值是:"+s.getName());
System.out.println("开始克隆。。。。");
try {
Student sClone = (Student)s.clone();
sClone.setAge(80);
sClone.setName("lisi");

System.out.println("克隆以后的对象的值是:"+sClone.getAge());
System.out.println("克隆以后的对象的值是:"+sClone.getName());

System.out.println("克隆之后的原始对象年龄值是:"+s.getAge());
System.out.println("克隆之后的原始对象名字值是:"+s.getName());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}


非常感谢!
1 楼 myloveiscomealone 2009-10-19  
分析得还可以,有深度克隆有浅克隆。
我给你补充一点!
package com.model.t22.simple;

public class Student implements Cloneable{
private int age;
private String name;
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 Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
package com.model.t22.simple;

public class SimpleTest {
public static void main(String[] args) {
Student s = new Student();
s.setAge(30);
s.setName("zhangsan");

System.out.println("克隆之前的原始对象年龄值是:"+s.getAge());
System.out.println("克隆之前的原始对象名字值是:"+s.getName());
System.out.println("开始克隆。。。。");
try {
Student sClone = (Student)s.clone();
sClone.setAge(80);
sClone.setName("lisi");

System.out.println("克隆以后的对象的值是:"+sClone.getAge());
System.out.println("克隆以后的对象的值是:"+sClone.getName());

System.out.println("克隆之后的原始对象年龄值是:"+s.getAge());
System.out.println("克隆之后的原始对象名字值是:"+s.getName());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}

相关推荐

    java_clone用法

    ### Java中的`clone`方法详解:浅拷贝与深拷贝 #### 一、引言 在Java中,`clone`方法提供了一种快速复制对象的方式。它属于`Object`类的一部分,但需要显式地在子类中声明并实现`Cloneable`接口才能正常使用。本文...

    java clone

    在Java编程语言中,`clone`是一个非常重要的概念,它涉及到对象复制和对象克隆。本文将深入探讨Java中的`clone`方法,包括其工作原理、使用场景、注意事项以及一些个人实践心得。 首先,让我们理解什么是`clone`。...

    Java深浅clone

    在Java编程语言中,`Cloneable`接口和`clone()`方法是两个重要的概念,它们用于对象复制。在本文中,我们将深入探讨Java中的浅克隆(shallow clone)和深克隆(deep clone),并结合测试代码进行分析。 首先,让...

    java clone的小例子

    总之,`clone()`方法在Java中提供了对对象复制的基本支持,尤其适用于需要创建对象副本的情况。然而,由于其浅拷贝的特性,开发者需要根据具体需求来决定是否使用它,或者选择其他复制策略,比如序列化和反序列化,...

    java中的指针,引用及对象的clone

    Java中的对象克隆可以通过实现`Cloneable`接口并覆盖`clone()`方法来完成。对象的克隆分为浅拷贝和深拷贝两种形式。 **1. 浅拷贝** 浅拷贝是指创建一个新的对象,然后将原对象的所有非引用类型的成员变量复制到新...

    Java中的克隆(Clone)机制

    在Java编程语言中,克隆(Clone)机制是一种创建对象副本的方法,它允许开发者创建一个已有对象的新实例,这个新实例与原对象具有相同的属性值,但却是两个独立的对象,彼此的操作不会互相影响。克隆机制在某些情况...

    Java中clone方法共6页.pdf.zip

    本资料"Java中clone方法共6页.pdf.zip"可能包含了关于如何理解和使用`clone()`方法的详细解释,以及它在实际开发中的应用示例。 `clone()`方法的主要用途是创建一个现有对象的副本,这个副本与原始对象具有相同的...

    java code clone

    因此,理解和处理Java代码克隆是软件开发中的一个重要话题。 首先,我们需要理解代码克隆的类型。根据克隆的相似程度,可以分为四种主要类型: 1. **精确克隆(Exact Clone)**:两个代码片段完全相同,包括空格和...

    Java的clone方法[归类].pdf

    Java的`clone()`方法在软件开发中扮演着重要的角色,特别是在需要复制对象的场景下。在Java中,对象的复制并非像C++等语言中的指针复制那样简单,因为Java中没有指针的概念,而是使用引用。这导致了在默认情况下,...

    clone()示例源码

    在Java编程语言中,`clone()`方法是一个非常重要的概念,特别是在处理对象复制和克隆时。这个方法源自`Object`类,是所有Java类的基类。`clone()`的使用通常涉及到深度复制和浅复制的概念,这两者在数据结构和内存...

    关于java clone的一些基本的概念

    在Java编程语言中,`clone`是一个非常重要的概念,它涉及到对象复制和对象的深拷贝与浅拷贝。本文将深入探讨Java中的`clone`方法及其相关知识点。 首先,`clone`方法是Java `Object`类的一个成员方法,定义为`...

    浅析Java中clone()方法浅克隆与深度克隆

    Java中的克隆(Clone)机制是面向对象编程中一种创建对象副本的方法,它允许程序员创建一个已有对象的新实例,新实例的数据与原对象相同。在Java中,克隆分为两种类型:浅克隆(Shallow Clone)和深度克隆(Deep ...

    如何通过JVM角度谈谈Java的clone操作

    Java中的对象创建主要有两种方式,即使用`new`操作符创建新对象以及通过`clone`方法复制已有对象。本文将从JVM的角度深入探讨Java的`clone`操作,揭示其工作原理及其潜在的问题。 首先,让我们理解`clone`方法的...

    java object 之clone方法全面解析

    Java中的`clone()`方法是Object类的一个成员方法,它提供了创建一个对象副本的功能。这篇文章将深入探讨`clone()`方法的工作原理、使用场景以及浅拷贝(shallow clone)与深拷贝(deep clone)的区别。 首先,让...

    Java clone方法详解及简单实例

    理解并正确使用`clone`方法是Java编程中的一个重要概念,尤其是在处理复杂对象图和需要创建对象副本的场景中。不过,`clone`方法有时可能会带来一些复杂性,例如需要处理`CloneNotSupportedException`,以及处理深...

    详解java中的深拷贝和浅拷贝(clone()方法的重写、使用序列化实现真正的深拷贝)

    在Java中,浅拷贝可以通过实现`Cloneable`接口并重写`clone()`方法来完成。以下是一个简单的浅拷贝示例: ```java public class Person implements Cloneable { private String name; private int age; private ...

    Java深复制与浅复制&Clone

    在Java中,浅复制可以通过`Object`类的`clone()`方法实现。但是,`clone()`方法默认的是浅复制,且需要被克隆的对象实现`Cloneable`接口。以下是一个简单的例子: ```java public class MyClass implements ...

    clone()方法示例(对象克隆)_对象克隆_nervouse78_源码

    总的来说,`clone()`方法是Java中一种快速创建对象副本的手段,但它需要开发者对浅拷贝和深拷贝有清晰的理解,并根据实际需求适当地处理对象的属性。通过`nervouse78`的示例,你可以学习到如何在实际项目中运用`...

Global site tag (gtag.js) - Google Analytics