如何使用clone()方法克隆Java对象 [英] How to clone a Java object with the clone() method

查看:280
本文介绍了如何使用clone()方法克隆Java对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不了解克隆自定义对象的机制。例如:

I don't understand the mechanism of cloning custom object. For example:

public class Main{

    public static void main(String [] args) {

        Person person = new Person();
        person.setFname("Bill");
        person.setLname("Hook");

        Person cloned = (Person)person.clone();
        System.out.println(cloned.getFname() + " " + cloned.getLname());
    }
}

class Person implements Cloneable{

    private String fname;
    private String lname;

    public Object clone() {

        Person person = new Person();
        person.setFname(this.fname);
        person.setLname(this.lname);
        return person;
    }

    public void setFname(String fname) {
        this.fname = fname;
    }

    public void setLname(String lname){
        this.lname = lname;
    }

    public String getFname(){
        return fname;
    }

    public String getLname() {
        return lname;
    }
}

此示例显示了正确的克隆方式书写。但是我可以在类名称定义中删除实现Cloneable的实现,并且得到相同的结果。

This is example shows right way of cloning as a in the books write. But I can delete implements Cloneable in the class name definition and I receive the same result.

所以我不理解Cloneable的提议,为什么clone()方法是在类对象中定义?

So I don't understand the proposing of Cloneable and why clone() method is defined in class Object?

推荐答案

clone方法用于制作深层副本。确保您了解深层副本和浅层副本之间的区别。在您的情况下,复制构造函数可能是您想要的模式。但是,在某些情况下,您不能使用此模式,例如,因为您正在对X类进行子类化,而您无权访问所需的X的构造函数。如果X正确地重写了其clone方法(如有必要),则可以通过以下方式进行复制:

The clone method is meant to make a deep copy. Make sure you understand the difference between deep and shallow copies. In your case a copy constructor may be the pattern you want. In some cases you can't use this pattern however, for example because you're subclassing class X and you don't have access to the constructor of X that you need. If X overrides its clone method correctly (if necessary) then you could make a copy in the following way:

class Y extends X implements Cloneable {

    private SomeType field;    // a field that needs copying in order to get a deep copy of a Y object

    ...

    @Override
    public Y clone() {
        final Y clone;
        try {
            clone = (Y) super.clone();
        }
        catch (CloneNotSupportedException ex) {
            throw new RuntimeException("superclass messed up", ex);
        }
        clone.field = this.field.clone();
        return clone;
    }

}

通常,覆盖克隆方法时:

In general when overriding your clone method:


  • 使返回类型更具体

  • 从调用 super开始.clone()

  • 当您知道 clone()也适用于不包含throws子句时任何子类(克隆模式的弱点;如果可能的话,使类最终化)

  • 将不可变和原始字段保留为空,但在调用之后手动克隆可变对象字段super.clone()(克隆模式的另一个弱点,因为无法将这些字段定为最终字段)

  • Make the return type more specific
  • Start with calling super.clone()
  • Do not include throws clause when you know clone() will also work for any subclass (weakness of the clone-pattern; make class final if possible)
  • Leave immutable and primitive fields alone, but clone mutable object fields manually after the call to super.clone() (another weakness of the clone-pattern, since these fields cannot be made final)

对象 clone()方法(最终,当所有超类都遵守合同时将被调用)浅拷贝,并照顾新对象的正确运行时类型。注意在整个过程中如何不调用构造函数。

The clone() method of Object (which will eventually be called when all superclasses obey the contract) makes a shallow copy and takes care of the correct runtime type of the new object. Note how no constructor is called in the entire process.

如果您希望能够调用 clone()在实例上,然后实现 Cloneable 接口并将该方法公开。如果您不想在实例上调用它,但是想确保子类可以调用其 super.clone()并获得所需的内容,然后不要实现 Cloneable ,如果您的超类尚未将其声明为公开,请保持方法 protected

If you want to be able to call clone() on instances, then implement the Cloneable interface and make the method public. If you don't want to be able to call it on instances, but you do want to make sure subclasses can call their super.clone() and get what they need, then don't implement Cloneable and keep the method protected if your superclass hasn't declared it public already.

克隆模式很困难并且有很多陷阱。确保这是您所需要的。考虑复制构造函数或静态工厂方法。

The clone pattern is difficult and has a lot of pitfalls. Be sure it's what you need. Consider copy constructors, or a static factory method.

这篇关于如何使用clone()方法克隆Java对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆