为什么要在Java中覆盖clone方法

时间:2012-10-26 18:08:38

标签: java clone

我对在我想要克隆对象的类中重写克隆方法感到困惑。

对象类具有受保护对象方法,并且根据受保护的行为当方法受到保护时,它只能由类本身,类的子类或类访问与班级相同的套餐

由于Java中的每个类都从Object扩展,所以它应该有克隆方法,但我们仍然被迫覆盖克隆。为什么需要它?

另外,我在某些地方读过覆盖克隆对象并将其公开。我想知道,为什么会这样?

欢迎所有答案。

5 个答案:

答案 0 :(得分:12)

  

由于Java中的每个类都从Object扩展,所以它应该有克隆   方法,但我们仍然被迫重写克隆

不,您不会被迫覆盖clone方法。在继承中,当您继承一个类时,您不必强制覆盖它的方法。它的修饰语是公共的或受保护的并没有多大区别。但是,如果要直接在super类引用上调用方法,则该方法必须为public。受保护的方法只能通过继承访问。也就是说,您只能通过subclass参考来访问它们。或者,如果您覆盖该方法,则可以通过super关键字访问它们。

话虽如此,您不应该覆盖clone方法,因为它是broken。因为,对于要克隆的类,您需要实现Cloneable接口。然后,您的班级使用clone类的Object方法代替。因为Cloneable接口并不完全具有cloning的任何方法。使用Copy Constructor代替是更好的选择。

public class A {
   private int data;
   public A() {
   }

   public A(A a) {
      this.data = a.data;
   }
}

有关详细信息,我建议您阅读Joshua Bloch's Effective Java的这一章,其中介绍了使用clone方法的所有方面。

Effective Java- Item # 11 - Override clone judiciously

答案 1 :(得分:5)

我建议阅读Joshua Bloch的Effective Java第2版。它有一个讨论克隆的好章节。

我不建议这样做。我认为这是JDK 1.0的错误。这本书会更清楚。

我建议编写一个复制构造函数来获得你想要的东西:

public class Foo {
    private String name;
    public Foo(String name) { this.name = name; }
    public Foo(Foo f) { this.name = f.name; }  // copy ctor here.
}

答案 2 :(得分:3)

在许多情况下,不清楚克隆对象应该是什么以及它应该如何表现,所以如果你希望你的类可以克隆,你必须通过重写克隆并将其公开来明确说明。

克隆可能没有意义的情况包括代表某些资源的类,如网络连接或同步锁。如果可以克隆这些对象,则不清楚克隆应该如何表现。例如,网络连接的克隆是否具有自己的TCP / IP连接,或者以某种方式使用现有连接?

答案 3 :(得分:1)

克隆是Protected类中的Object方法,因此您可以在课堂内访问它。

关于访问 - 当一个方法受到保护时,它只能由类本身,类的子类或与该类相同的包中的类访问。

我看到一些关于克隆方法的误解

  1. clone()方法在protected课程中为Object,因此您无法在课堂外调用clone()。例如child.clone()除非您覆盖它并进行访问public
  2. Cloneable是标记界面,如果您没有标记类Cloneable,那么如果您调用CloneNotSupportedException方法
  3. ,您将获得clone()
  4. 如果一个类只包含原始字段或对不可变对象的引用,那么通常情况是super.clone返回的对象中的任何字段都不需要修改。
  5. 按照惯例,应该通过调用super.clone来获取返回的对象。如果一个类及其所有superclasses (except Object)遵守此约定,那么x.clone().getClass() == x.getClass()就是这种情况。
  6. 方法签名在

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

    参考文献:

    1. Object#clone()
    2. Cloneable

答案 4 :(得分:-1)

    Why we do override clone() in cloning process?
    //clone() in Object class is protected
    package java.lang;


    protected native Object clone()
            throws CloneNotSupportedException;

    java.lang is default import in our java applications.

Note: If parent and sub class are both in same package then the methods in parent class are directly accessible. If they are in different package,then in subclass we have to override the parent class methods to use.

    Note:Object class is in java.lang package,we are using it in different package,so we have to override the clone() which is protected in Object class


first we will look into Protected method behavior.here is sample program to understand this
    //this class is in com.anusha.clonetrial
    package com.anusha.clonetrial;

    public class A {

        public A()
        {

        }
        protected void disp1()
        {
            System.out.println("class a");
        }
        protected void disp2()
        {
            System.out.println("class a");
        }
    }
    //below classes are in com.anusha.Test
    package com.anusha.Test;
    import com.anusha.clonetrial.A;


    class AA {


        protected void disp1()
        {
            System.out.println("class aa");
        }

        protected void disp2()
        {
            System.out.println("class aa");
        }
    }

    //class B derived from AA which is present in the same package
    class B extends AA
    {

        void show()
        {


            System.out.println("class b");
        }
    }

    //class C derived from A which is present in the different package

    class C extends A
    {

        @Override
        protected void disp1()
        {
            super.disp1();
        }
        void show()
        { 
            System.out.println("class c");
        }
    }

    package com.anusha.Test;




    public class CloneTest {


        public static void main(String[] args) {
            B b=new B();
            C c=new C();
            b.disp1();
            b.disp2();
            c.disp1();
            c.disp2();//gives error because it is not overridden.


        }

    }