`
yangyangmyself
  • 浏览: 233875 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Object的clone()方法、深拷贝、浅拷贝

    博客分类:
  • Java
 
阅读更多
obj.clone().getClass()==obj.getClass(),即它们具有相同的类型。还有一点,因为只是简单的将对象的空间进行复制,所以如果类具有引用类型的实例变量的话,也只是将这个引用进行拷贝,并不复制其引用的对象。这就导致拷贝对象的引用实例变量与原对象的指向相同的对象,这就是传说中的“浅拷贝”。如果实例变量引用的对象是不可变的,类似于String,则拷贝对象与原对象不能互相影响,这样的拷贝是成功的。但是如果引用的是可变对象,它们就会影响彼此,对于成功的拷贝而言,这是不允许的。可以对可变的实例变量对象进行特殊处理,以实现拷贝对象和原对象不能相互影响的“深拷贝”。

      由于Object.clone()方法是protected的,所以它只能在lang包中的类或是其子类的方法内部被调用,所以,如果像下面这样调用,会编译出错,在Person kobe_bak=kobe.clone();报错,说clone只能在Object的protected作用域访问。

class Person implements Cloneable  
{  
    private int age;  
    private String name;  
    private Date birth;  
    public Person(int a,String n,Date b){     
        age=a;  
    name=n;  
    birth=b;  
    }  
      
    public static void main(String[] args){  
        Person kobe=new Person(33,"kobe",new Date());  
        Person kobe_bak=kobe.clone();  
    }  
}  


clone方法的作用域限制不允许我们在其它地方访问,那我们就重写Object的clone方法,并扩大访问作用域为public,在Person类中添加clone的方法重写,调用super.clone(),也就是Object.clone()。

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


然后编译,可以通过,接着运行程序,结果在Person kobe_bak=kobe.clone();抛出CloneNotSupportedException异常。这是因为Java只有一个类实现了Cloneable接口,才表示这个类可以被克隆。所以要想拷贝一个类的对象,必须让它实现Cloneable接口。这个接口只是一个标记接口,没有声明任何方法。

     接下来,让Person类实现Cloneable接口,然后编译,运行,这个对象就被成功的克隆了。所以要想一个类可以被clone,必须满足两点:
第一,它必须实现了Cloneable接口,否则会抛出CloneNotSupportedException异常。
第二,它必须提供一个public的clone方法,也就是重写Object.clone()方法,否则编译不能通过。
第三,对于存在可变域的类,在clone方法中需要对这些可变域进行拷贝。

class Person implements Cloneable  
{  
    private int age;  
    private String name;  
    private Date birth;  
    public Person(int a,String n,Date b){     
        age=a;  
    name=n;  
    birth=b;  
    }  
      
    public static void main(String[] args){  
        Person kobe=new Person(33,"kobe",new Date());  
        Person kobe_bak=kobe.clone();  
    }  
    @Override  
    public Object clone(){  
        Person p=(Person)super.clone();  
        //Date类型的birth域是可变变的,需要对其克隆,进行深拷贝  
        //Date类实现的克隆,直接调用即可  
        p.birth=this.birth.clone();  
        return p;  
    }  
}  


                                            转自:http://www.crazyit.org
分享到:
评论

相关推荐

    深拷贝浅拷贝.zip

    在C#中,实现深拷贝有多种方法,包括手动实现Clone方法、使用序列化和反序列化,以及使用第三方库如AutoMapper。 以下是通过序列化和反序列化实现深拷贝的例子: ```csharp using System.IO; using System.Runtime...

    C#浅拷贝深拷贝

    在这个例子中,`Clone()`方法创建了一个新的`MyClass`实例,并且通过创建新的字符串对象实现了深拷贝。 `CloneDemo`可能是一个示例项目,它包含了关于如何在C#中实现浅拷贝和深拷贝的代码。通过分析和运行这个项目...

    C#浅拷贝(MemberwiseClone等多种方法)与深拷贝(反射、多种反序列化)实例

    首先,浅拷贝是通过`Object.MemberwiseClone()`方法来实现的。这个方法为对象创建一个新的实例,然后将当前对象的字段值复制到新实例中。如果字段包含的是引用类型,那么新旧对象会共享同一引用。例如: ```csharp ...

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

    `TestString`类中的`main`方法展示了浅拷贝、默认`clone()`方法实现的深拷贝以及序列化实现的深拷贝的用法。`qianCopyTest()`展示了浅拷贝的效果,其中对于包含可变对象的`Person`实例,修改副本会影响原始对象。`...

    【ASP.NET编程知识】浅谈.net平台下深拷贝和浅拷贝.docx

    在这个例子中,`ClassB` 的 `Clone()` 方法通过调用 `Member.Clone()` 来为 `Member` 字段创建一个深拷贝。 ### 应用场景 选择使用深拷贝还是浅拷贝取决于具体需求。如果对象的字段只包含值类型或者不需要独立于...

    C#中的浅拷贝和深拷贝

    ### C#中的浅拷贝与深拷贝 在C#编程语言中,对象的复制是一项基本而重要的操作。根据复制的方式不同,可以分为浅拷贝(Shallow Copy)和深拷贝(Deep Copy)。这两种复制方式各有其特点和适用场景。 #### 值类型...

    深入理解JavaScript中的对象复制(Object Clone)

    在深入探讨JavaScript中的对象复制(Object Clone)时,首先需要明确JavaScript中的对象复制分为浅复制(Shallow Copy)和深复制(Deep Copy)。浅复制指的是创建一个新对象,这个对象有着原始对象属性值的一份精确...

    java对象的深拷贝和浅拷贝[归类].pdf

    在Java中实现深拷贝通常需要重写`clone()`方法并实现`Cloneable`接口。 ```java class A { public int i; public int j; public A clone() { A a1 = new A(); a1.i = this.i; a1.j = this.j; return a1; ...

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

    - 默认的`Object.clone()`方法只执行浅拷贝。为了实现深拷贝,通常需要在自定义类中重写`clone()`方法,并且确保所有的引用字段也被正确复制。 4. **安全性与并发考虑**: - `clone()`方法不会调用构造函数,因此...

    浅谈Java中实现深拷贝的两种方式—clone() & Serialized

    clone()方法是Object类中的一个方法,它可以用来实现对象的浅拷贝。但是,如果我们想要实现深拷贝,那么需要将所有涉及到的类实现声明式接口Cloneable,并覆盖Object类中的clone()方法,并设置作用域为public。这是...

    java object 之clone方法全面解析

    这篇文章将深入探讨`clone()`方法的工作原理、使用场景以及浅拷贝(shallow clone)与深拷贝(deep clone)的区别。 首先,让我们了解`clone()`方法的定义: ```java protected native Object clone() throws ...

    java_clone用法

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

    Java中的深拷贝(深复制)和浅拷贝(浅复制)介绍

    在Java中,通过实现`Cloneable`接口并覆盖`Object`类的`clone()`方法,可以实现浅拷贝。以下代码展示了浅拷贝的例子: ```java public class ShallowCopy { public static void main(String[] args) { Professor0...

    《剑指offer》Java浅拷贝和深拷贝.pdf

    在Java中,可以通过实现`Cloneable`接口并重写`clone()`方法来实现浅拷贝。例如: ```java public class Food implements Cloneable { ... @Override protected Object clone() throws ...

    java设计模式【之】原型模式、深拷贝与浅拷贝【源码】【场景:克隆羊】

    * 需要被克隆的 class类, 重写Object中的clone()方法,并实现Cloneable接口(否则报错 CloneNotSupportedException) * 注意: * 1.被克隆对象.clone()出的对象,是被克隆对象的当前状态 * 2.被克隆对象 如果...

    Java 细数浅拷贝和深拷贝

    实现浅拷贝的方式之一是通过实现`Cloneable`接口并重写`clone()`方法。例如: ```java public class Food implements Cloneable { // ... 其他代码 ... @Override protected Object clone() throws ...

    c# 深拷贝与浅拷贝的区别分析及实例

    实现深拷贝通常需要手动编写代码来复制每个字段,或者实现`ICloneable`接口并重写`Clone()`方法。 以下是一个简单的例子来说明深拷贝和浅拷贝的区别: ```csharp public class Person { public int Age { get; ...

    java Clone

    // 这里可以添加对其他复杂类型的深拷贝逻辑 return o; } } ``` 在上述代码中,`super.clone()`调用了`Object`类的`clone`方法,这是一个本地方法(native),效率较高。需要注意的是,`Object`类的`clone`方法...

    结合JVM解读浅拷贝和深拷贝

    总的来说,了解`Cloneable`接口、`Object.clone()`方法以及浅拷贝和深拷贝的概念对于编写高质量、健壮的Java代码是至关重要的。正确使用这些机制能够帮助开发者创建可维护、可扩展的系统,并确保数据的正确复制和...

    浅谈C#中ListT对象的深度拷贝问题

    一、List对象中的T是值类型的情况(int 类型等) 对于值类型的List直接用以下方法就可以复制: List<T> oldList = new List(); oldList.Add(..); List<T> newList = new List... public static IList<T> Clone(t

Global site tag (gtag.js) - Google Analytics