为什么要在Java中重写clone方法

关于在我想要克隆对象的类中重写克隆方法,我很困惑。

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

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

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

欢迎所有答案。

由于Java中的每个类都从Object扩展,因此它应该具有克隆方法,但我们仍然被迫覆盖克隆

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

话虽如此,你不应该重写clone方法,因为它被broken 。 因为,对于要克隆的类,您需要实现Cloneable接口。 然后你的类使用Object类的clone方法。 因为, 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方法的所有方面。

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

我建议阅读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. } 

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

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

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

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

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

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

方法签名如下

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

参考文献:

  1. 对象#克隆()
  2. 可复制
  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. } }