关于Cloneable接口以及应该抛出的异常的问题
Java 文档说:
一个类实现了Cloneable 接口来指示 Object.clone() 方法就是这样 该方法合法地制作 实例的字段对字段副本 那个班级。
调用对象的克隆方法 没有实现的实例 可克隆接口导致 异常 CloneNotSupportedException 被抛出。
按照惯例,实现的类 这个接口应该覆盖 Object.clone(受保护)与 一个公共方法。请参阅 Object.clone() 有关重写此方法的详细信息。
请注意,该接口不 包含克隆方法。所以, 不可能克隆一个对象 仅仅因为它 实现了这个接口。即使 反射性地调用clone方法, 无法保证它会 成功。
我有这个 UserProfile 类:
public class UserProfile implements Cloneable {
private String name;
private int ssn;
private String address;
public UserProfile(String name, int ssn, String address) {
this.name = name;
this.ssn = ssn;
this.address = address;
}
public UserProfile(UserProfile user) {
this.name = user.getName();
this.ssn = user.getSSN();
this.address = user.getAddress();
}
// get methods here...
@Override
public UserProfile clone() {
return new UserProfile(this);
}
}
为了测试 porpuses,我在 main() 中执行此操作:
UserProfile up1 = new UserProfile("User", 123, "Street");
UserProfile up2 = up1.clone();
到目前为止,编译/运行没有问题。现在,根据我对文档的理解,从 UserProfile
类中删除 implements Cloneable
应该在 up1.clone()
调用中引发异常,但是事实并非如此。
我在这里读到 Cloneable 接口已损坏,但我真的不知道这意味着什么。我错过了什么吗?
The Java documentation says:
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.
And I have this UserProfile
class:
public class UserProfile implements Cloneable {
private String name;
private int ssn;
private String address;
public UserProfile(String name, int ssn, String address) {
this.name = name;
this.ssn = ssn;
this.address = address;
}
public UserProfile(UserProfile user) {
this.name = user.getName();
this.ssn = user.getSSN();
this.address = user.getAddress();
}
// get methods here...
@Override
public UserProfile clone() {
return new UserProfile(this);
}
}
And for testing porpuses, I do this in main()
:
UserProfile up1 = new UserProfile("User", 123, "Street");
UserProfile up2 = up1.clone();
So far, no problems compiling/running. Now, per my understanding of the documentation, removing implements Cloneable
from the UserProfile
class should throw an exception in up1.clone()
call, but it doesn't.
I've read around here that the Cloneable interface is broken but I don't really know what that means. Am I missing something?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
只要您的类仍然具有
clone()
方法的实现,那么当您调用它时就不会抛出异常 - 它的工作方式就像任何其他方法一样,没有涉及特殊的魔法。Object
类中clone()
的实现引发了异常,但您已经重写了该方法。As long as your class still has an implementation of the
clone()
method, an exception will ofcourse not be thrown when you call it - it works just like any other method, there's no special magic involved.The implementation of
clone()
in classObject
is what throws the exception, but you've overridden that method.这意味着如果你实现 Cloneable 并省略clone()方法然后调用clone()方法,将会抛出异常。
编辑:之前可能已被提及 10 亿次,但是
如果您需要克隆功能,请提供复制构造函数。
该接口被称为损坏的,因为它不会强制您实现clone()(它应该实现)。
It means that if you implements Cloneable and omit the clone() method and THEN call the clone() method, an exception will be thrown.
EDIT: It has been mentioned probably 1 billion times before, but
If you need cloning functionality, provide a copy constructor instead.
The interface is called broken because it doesn't force you to implement clone() (which it should).
我同意这两个答案并添加一些内容:接口就像一个“标签”,表明您的类实现了clone()。当您不知道对象类型时,这在类似 api 的方法中非常有用。然后你可以写
I agree with both answers and add something: the interface is like a 'tag' to say that your class implements clone(). That's useful in api-like methods when you don't know the object type. Then you can write