2

Java 文档说:

一个类实现了 Cloneable 接口,以向 Object.clone() 方法指示该方法可以合法地对该类的实例进行逐个字段的复制。

在未实现 Cloneable 接口的实例上调用 Object 的 clone 方法会导致抛出异常 CloneNotSupportedException。

按照惯例,实现此接口的类应使用公共方法覆盖 Object.clone(受保护的)。有关覆盖此方法的详细信息,请参阅 Object.clone()。

请注意,此接口不包含 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();

到目前为止,编译/运行没有问题。现在,根据我对文档的理解,implements CloneableUserProfile类中删除应该会在调用中引发异常up1.clone(),但事实并非如此。

我在这里读到 Cloneable 接口坏了,但我真的不知道这意味着什么。我错过了什么吗?

4

3 回答 3

5

现在,根据我对文档的理解,implements CloneableUserProfile类中删除应该在调用中抛出和异常up1.clone(),但事实并非如此。

只要您的类仍然具有该clone()方法的实现,当您调用它时当然不会抛出异常 - 它就像任何其他方法一样工作,不涉及特殊魔法。

clone()类中的实现Object是引发异常的原因,但是您已经覆盖了该方法。

于 2010-05-22T15:51:22.817 回答
1

这意味着如果您实现 Cloneable 并省略 clone() 方法,然后调用 clone() 方法,则会引发异常。

编辑:之前可能已经提到了 10 亿次,但是

不要使用克隆方法!

如果您需要克隆功能,请提供一个复制构造函数。

该接口被称为损坏,因为它不会强制您实现 clone() (它应该)。

于 2010-05-22T15:52:22.517 回答
1

我同意这两个答案并添加一些内容:接口就像一个“标签”,表示您的类实现了 clone()。当您不知道对象类型时,这在类似 api 的方法中很有用。然后你可以写

if (myobj instanceof Cloneable) { dosmthng(); }
于 2010-05-22T15:58:54.293 回答