为什么要覆盖 Java 中的克隆方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13092128/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 11:26:57  来源:igfitidea点击:

Why to override clone method in Java

javaclone

提问by Anand

I am confused regarding overriding clone method in the class for which I want cloned object.

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

Object class has protected objectmethod and as per the protected behavior which is When a method is protected, it can only be accessed by the class itself, subclasses of the class, or classes in the same package as the class.

对象类有受保护的对象方法,根据受保护的行为,当一个方法被保护时,它只能被类本身、类的子类或与类在同一个包中的类访问

As every class in Java extends from Object, so it should have clone method but still we are forced to override clone. Why is it required?

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

Also, I have read at some places to override the clone object and make it public. I wonder, why is it so?

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

All answers are welcome.

欢迎所有答案。

采纳答案by Rohit Jain

As every class in Java extends from Object, so it should have clone method but still we are forced to override clone

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

No you are not forced to override the clonemethod. In inheritance, when you inherit a class, you are not forced to override it's method. Its modifier being public or protected doesn't make much of a difference. However, if you want to invoke a method directly on superclass reference, then that method has to be public. Protected methods are accessible only through inheritance. That is you can only access them through subclassreference. Or if you override the method, you can access them through superkeyword.

不,您不会被迫覆盖该clone方法。在继承中,当您继承一个类时,您不会被迫覆盖它的方法。它的修饰符是 public 还是 protected 并没有太大区别。但是,如果您想直接在super类引用上调用一个方法,那么该方法必须是public. 受保护的方法只能通过继承访问。也就是说,您只能通过subclass引用访问它们。或者,如果您覆盖该方法,则可以通过super关键字访问它们。

Having said that, you should not override clonemethod, as it is broken. Because, for a class to be cloned, you need to implement the Cloneableinterface. And then your class uses the clonemethod of Objectclass instead. Because, Cloneableinterface doesn't exactly have any method for cloning. It would be a better option to use Copy Constructorinstead.

话虽如此,您不应该覆盖clone方法,因为它是broken。因为,要克隆一个类,您需要实现该Cloneable接口。然后你的班级改用班级的clone方法Object。因为,Cloneableinterface 没有任何方法用于cloning. 使用它会是一个更好的选择Copy Constructor

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

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

For more details, I would suggest to go through this chapter of Joshua Bloch'sEffective Java, which covers all aspects of using clonemethod.

有关更多详细信息,我建议您阅读Joshua Bloch'sEffective Java 的这一章,它涵盖了使用clone方法的所有方面。

Effective Java- Item # 11 - Override clone judiciously

有效的 Java - 项目 #11 - 明智地覆盖克隆

回答by duffymo

I'd recommend reading Joshua Bloch's Effective Java2nd edition. It has a good chapter discussing clone.

我建议阅读 Joshua Bloch 的Effective Java2nd edition。它有一个很好的章节讨论克隆。

I would not advise doing this. I consider this a JDK 1.0 mistake. The book will make that clearer.

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

I'd recommend writing a copy constructor instead to get what you want:

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

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

回答by Joni

In many cases it's not clear what a cloned object should be and how it should behave, so if you want your class to be clonable you have to say so explicitly by overriding clone and making it public.

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

Cases where clone might not make sense include classes that represent some resource, like a network connection or a synchronization lock. If these objects could be cloned it's not clear how the clone should behave. For example, does the clone of a network connection have a TCP/IP connection of its own or does it somehow use the existing one?

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

回答by Amit Deshpande

Clone is Protectedmethod in Objectclass so it is accessible to you inside class.

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

About access- When a method is protected, it can only be accessed by the class itself, subclasses of the class, or classes in the same package as the class.

关于访问——当一个方法被保护时,它只能被类本身、类的子类或与类在同一个包中的类访问。

I see some misconceptions about clone method

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

  1. clone()method is protectedinside Objectclass so you can not call clone()outside of class. e.g. child.clone()unless you override it and make access public
  2. Cloneableis marker interface and if you do not mark class Cloneablethen you will get CloneNotSupportedExceptionif you call clone()method
  3. If a class contains only primitive fields or references to immutable objects, then it is usually the case that no fields in the object returned by super.cloneneed to be modified.
  4. By convention, the returned object should be obtained by calling super.clone. If a class and all of its superclasses (except Object)obey this convention, it will be the case that x.clone().getClass() == x.getClass().
  1. clone()方法protectedObject类内部,因此您不能在类clone()外部调用 。例如,child.clone()除非您覆盖它并进行访问public
  2. Cloneable是标记接口,如果不标记类,CloneableCloneNotSupportedException调用clone()方法会得到
  3. 如果一个类只包含原始字段或对不可变对象的引用,那么通常情况下返回的对象中没有字段super.clone需要修改。
  4. 按照惯例,返回的对象应该通过调用获取super.clone。如果一个类及其所有的类都superclasses (except Object)遵守这个约定,那么x.clone().getClass() == x.getClass().

Method signature is below

方法签名如下

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

References :

参考 :

  1. Object#clone()
  2. Cloneable
  1. 对象#clone()
  2. 可克隆

回答by anusha

    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.


        }

    }