关于Cloneable接口以及应该抛出的异常的问题

发布于 2024-09-02 17:36:53 字数 1382 浏览 4 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

皇甫轩 2024-09-09 17:36:53

现在,根据我对文档的理解,从 UserProfile 类中删除 implements Cloneable 应该在 up1.clone() 中抛出异常调用,但没有。

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

Object 类中 clone() 的实现引发了异常,但您已经重写了该方法。

Now, per my understanding of the documentation, removing implements Cloneable from the UserProfile class should throw and exception in up1.clone() call, but it doesn't.

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 class Object is what throws the exception, but you've overridden that method.

记忆之渊 2024-09-09 17:36:53

这意味着如果你实现 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

DON'T USE THE CLONE METHOD!

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).

天冷不及心凉 2024-09-09 17:36:53

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

if (myobj instanceof Cloneable) { dosmthng(); }

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

if (myobj instanceof Cloneable) { dosmthng(); }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文