java 让我的班级实现 Cloneable 有什么意义?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16507676/
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
What is the point in letting my class implement Cloneable?
提问by Emil Adz
I came across some class code that implements Clonable
, the documentation states:
我遇到了一些实现 的类代码,Clonable
文档指出:
A class implements the Cloneable interface to indicate to the Object.clone() method that it is legal for that method to make a field-for-field copy of instances of that class. Invoking Object's clone method on an instance that does not implement the Cloneable interface results in the exception CloneNotSupportedException being thrown. By convention, classes that implement this interface should override Object.clone (which is protected) with a public method. See Object.clone() for details on overriding this method. Note that this interface does not contain the clone method. Therefore, it is not possible to clone an object merely by virtue of the fact that it implements this interface. Even if the clone method is invoked reflectively, there is no guarantee that it will succeed.
一个类实现了 Cloneable 接口,以向 Object.clone() 方法指示该方法制作该类实例的字段对字段副本是合法的。在未实现 Cloneable 接口的实例上调用 Object 的 clone 方法会导致抛出异常 CloneNotSupportedException。按照惯例,实现此接口的类应该使用公共方法覆盖 Object.clone(受保护)。有关覆盖此方法的详细信息,请参阅 Object.clone()。请注意,此接口不包含 clone 方法。因此,不能仅仅凭借对象实现了这个接口就克隆一个对象。即使以反射方式调用 clone 方法,也不能保证它会成功。
I can't understand the point in implementing this class, as said in the docs the .clone
method is not implemented in the interface, and I have to implement it. So why use this class? Why won't I just write a method copyClass
in my class to make the object copy without the implementation of this class?
我无法理解实现这个类的意义,正如文档中所说,该.clone
方法没有在接口中实现,我必须实现它。那么为什么要使用这个类呢?为什么我不在copyClass
我的类中写一个方法来复制对象而不实现这个类?
回答by JB Nizet
To implement the clone method, you simply do:
要实现 clone 方法,您只需执行以下操作:
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
You can of course customize the method to make a deeper copy if needed.
如果需要,您当然可以自定义方法以制作更深的副本。
Calling super.clone()
is almost mandatory because, unless the class is final and thus can't be overridden, the clone()
method must return an instance of the same class as the object on which it's called. So simply creating a new instance and copy the state will work for this class, but not for all the subclasses. Moreover, you don't always have access to all the state contained in superclasses.
调用super.clone()
几乎是强制性的,因为除非类是 final 并且因此不能被覆盖,否则该clone()
方法必须返回与调用它的对象相同的类的实例。因此,简单地创建一个新实例并复制状态将适用于此类,但不适用于所有子类。此外,您并不总是可以访问超类中包含的所有状态。
In short, you make the protected clone method of Object public. And the first thing that the Object.clone()
method does is (this is not the real code, but this is what the method does):
简而言之,您将 Object 的受保护克隆方法设为公开。该Object.clone()
方法所做的第一件事是(这不是真正的代码,但这就是该方法所做的):
if (!(this instanceof Cloneable)) {
throw new CloneNotSupportedException();
}
So, Cloneable
is just a marker interface to let the Object.clone()
method know that it must not throw an exception when called.
所以,Cloneable
只是一个标记接口,让Object.clone()
方法知道它在调用时不能抛出异常。
This is one of the most badly-designed parts of Java. Usually, you should prefer using a copy contructor instead of using clone()
.
这是 Java 设计最糟糕的部分之一。通常,您应该更喜欢使用复制构造函数而不是使用clone()
.
回答by Mateusz
It allows you to write more generic code. If you have multiple classes implementing Cloneable
interface, and want to pass their instances as an argument to method, you don't have to create multiple methods differing with one variable type, you can just use Cloneable t
. It's the same with other interfaces. And, the same with every other interface, it's kinda multiple inheritance. Implementing those interfaces makes your code more legible too.
它允许您编写更通用的代码。如果您有多个实现Cloneable
接口的类,并希望将它们的实例作为参数传递给方法,则不必创建多个与一种变量类型不同的方法,您只需使用Cloneable t
. 其他接口也一样。而且,与其他所有接口一样,它有点多重继承。实现这些接口也使您的代码更易读。
回答by Mindaugas Bernatavi?ius
In addition to what others said, Cloneable is often used when implementing prototype design pattern.
除了其他人所说的,在实现原型设计模式时,经常使用 Cloneable。