Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 关于可克隆接口和应引发的异常的问题_Java_Exception_Interface_Clone_Cloneable - Fatal编程技术网

Java 关于可克隆接口和应引发的异常的问题

Java 关于可克隆接口和应引发的异常的问题,java,exception,interface,clone,cloneable,Java,Exception,Interface,Clone,Cloneable,Java文档说明: 类实现了可克隆性 接口,用于向 Object.clone()方法,它是 合法的方法使 的实例的逐字段副本 那个班 在对象上调用对象的克隆方法 未实现 可克隆接口导致 异常CloneNotSupportedException 被扔了 按照惯例,实现 此接口应重写 Object.clone(受保护)与 公开的方法。请参阅Object.clone() 有关重写此方法的详细信息 请注意,此接口不可用 包含克隆方法。所以,, 无法克隆对象 仅仅是因为它 实现这个接口。即使 反射地调用克

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(); }