Java 关于可克隆接口和应引发的异常的问题
Java文档说明: 类实现了可克隆性 接口,用于向 Object.clone()方法,它是 合法的方法使 的实例的逐字段副本 那个班 在对象上调用对象的克隆方法 未实现 可克隆接口导致 异常CloneNotSupportedException 被扔了 按照惯例,实现 此接口应重写 Object.clone(受保护)与 公开的方法。请参阅Object.clone() 有关重写此方法的详细信息 请注意,此接口不可用 包含克隆方法。所以,, 无法克隆对象 仅仅是因为它 实现这个接口。即使 反射地调用克隆方法, 不能保证它会 成功 我有一个Java 关于可克隆接口和应引发的异常的问题,java,exception,interface,clone,cloneable,Java,Exception,Interface,Clone,Cloneable,Java文档说明: 类实现了可克隆性 接口,用于向 Object.clone()方法,它是 合法的方法使 的实例的逐字段副本 那个班 在对象上调用对象的克隆方法 未实现 可克隆接口导致 异常CloneNotSupportedException 被扔了 按照惯例,实现 此接口应重写 Object.clone(受保护)与 公开的方法。请参阅Object.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);
}
}
为了测试porpus,我在main()
中这样做:
到目前为止,编译/运行没有问题。现在,根据我对文档的理解,从UserProfile
类中删除implements Cloneable
应该会在up1.clone()
调用中引发异常,但它不会
我在这里读到过,可克隆的界面被破坏了,但我真的不知道这意味着什么。我错过什么了吗
现在,根据我对文档的理解,从UserProfile
类中删除implements Cloneable
应该在up1.clone()
调用中抛出异常,但它没有
只要您的类仍然有clone()
方法的实现,当您调用它时,当然不会抛出异常-它的工作原理与任何其他方法一样,没有特殊的魔力
类
Object
中clone()
的实现是引发异常的原因,但您已经重写了该方法。这意味着如果您实现Cloneable并省略clone()方法,然后调用clone()方法,将引发异常
编辑:它以前可能被提到过10亿次,但是
不要使用克隆方法
如果需要克隆功能,请提供复制构造函数
接口之所以被称为断开,是因为它不强制您实现clone()(它应该实现)。我同意这两个答案,并添加了一些内容:接口就像一个“标签”,表示您的类实现了clone()。当您不知道对象类型时,这在类似api的方法中非常有用。然后你就可以写了
if (myobj instanceof Cloneable) { dosmthng(); }
如果我用自己的实现重写clone方法,那么不使用clone方法的理由是什么?仅仅实现一个复制构造函数可能会导致继承方面的其他问题。我不明白为什么一个比另一个更糟。在这种情况下,为什么不坚持使用标准Cloneable?至少大多数开发人员知道它的缺点并能处理它们。就我所见,我正在重写类中的clone方法,它所做的只是调用copy构造函数。“这有什么问题?”Nazgulled Sry没有看到复制构造函数。但是为什么你的克隆方法不直接调用super.clone()?你应该使用
instanceof
而不是is
。更正了,我把东西和C混淆了。谢谢。Cloneable是有问题的,因为Cloneable接口没有clone()方法,您要么需要知道实现clone()方法的特定类型(在这种情况下,您需要知道具体类型,因此可以使用复制构造函数),要么必须使用反射。任何需要反射才能正常工作的API都可能被描述为已损坏。请注意:在克隆方法中,不要调用构造函数,而是调用(UserProfile)super.clone()。请参阅“按约定…”至少涉及一些技巧,因为通过super.clone()调用Object.clone()时不会引发该异常。但是除此之外,我同意。Object.clone()
检查对象是否是实现Cloneable
的类的实例,如果不是,则抛出异常。不需要特殊的魔法(例如编译器的特殊处理)。。。
if (myobj instanceof Cloneable) { dosmthng(); }