为什么要覆盖 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
Why to override clone method in Java
提问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 clone
method. 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 super
class reference, then that method has to be public
. Protected methods are accessible only through inheritance. That is you can only access them through subclass
reference. Or if you override the method, you can access them through super
keyword.
不,您不会被迫覆盖该clone
方法。在继承中,当您继承一个类时,您不会被迫覆盖它的方法。它的修饰符是 public 还是 protected 并没有太大区别。但是,如果您想直接在super
类引用上调用一个方法,那么该方法必须是public
. 受保护的方法只能通过继承访问。也就是说,您只能通过subclass
引用访问它们。或者,如果您覆盖该方法,则可以通过super
关键字访问它们。
Having said that, you should not override clone
method, as it is broken
. Because, for a class to be cloned, you need to implement the Cloneable
interface. And then your class uses the clone
method of Object
class instead. Because, Cloneable
interface doesn't exactly have any method for cloning
. It would be a better option to use Copy Constructor
instead.
话虽如此,您不应该覆盖clone
方法,因为它是broken
。因为,要克隆一个类,您需要实现该Cloneable
接口。然后你的班级改用班级的clone
方法Object
。因为,Cloneable
interface 没有任何方法用于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's
Effective Java, which covers all aspects of using clone
method.
有关更多详细信息,我建议您阅读Joshua Bloch's
Effective Java 的这一章,它涵盖了使用clone
方法的所有方面。
回答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 Protected
method in Object
class 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
我看到了一些关于克隆方法的误解
clone()
method isprotected
insideObject
class so you can not callclone()
outside of class. e.g.child.clone()
unless you override it and make accesspublic
Cloneable
is marker interface and if you do not mark classCloneable
then you will getCloneNotSupportedException
if you callclone()
method- 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.clone
need to be modified. - By convention, the returned object should be obtained by calling
super.clone
. If a class and all of itssuperclasses (except Object)
obey this convention, it will be the case thatx.clone().getClass() == x.getClass()
.
clone()
方法protected
在Object
类内部,因此您不能在类clone()
外部调用 。例如,child.clone()
除非您覆盖它并进行访问public
Cloneable
是标记接口,如果不标记类,Cloneable
则CloneNotSupportedException
调用clone()
方法会得到- 如果一个类只包含原始字段或对不可变对象的引用,那么通常情况下返回的对象中没有字段
super.clone
需要修改。 - 按照惯例,返回的对象应该通过调用获取
super.clone
。如果一个类及其所有的类都superclasses (except Object)
遵守这个约定,那么x.clone().getClass() == x.getClass()
.
Method signature is below
方法签名如下
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
References :
参考 :
回答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.
}
}