第一次创建复制方法

时间:2016-10-29 20:13:08

标签: java clone

我正在尝试创建一个复制方法,但我所拥有的似乎太简单了,我认为它基本上什么都不做。

public Validation copy(Validation newValidation){return newValidation;}

所以如果这样实施:

Validation x = new Validation(); 
Validation y = x.copy(x);

然后确保y具有x的所有方法/变量,并且当使用y中的变量时,我不会影响x中的变量。我有一种感觉,我想要的是一个“深层复制”方法,我在这里找到了一篇关于它的帖子:Creating a deep copy method, Java但是那个人对他们的方法没有任何争论,所以我不知道它是如何实际复制的。 / p>

2 个答案:

答案 0 :(得分:1)

是的,除了返回已经传递的相同引用外,它什么都不做。

可能您正在寻找Object#clone() *方法:

public Validation copy(Validation newValidation) {
    return newValidation.clone();
}

在95%的情况下,这是针对不同类型任务的最合适和最合适的解决方案。如果不需要它,你不应该重新发明轮子。

正如Java文档所说:

  

...此方法执行此对象的“浅层复制”,而非“深层复制”操作。

     

...在返回之前,可能需要修改super.clone返回的对象的一个​​或多个字段。

Validation y = x.copy(x);

您不应该将x传递给copy方法,因为当您在x实例上调用此方法时,您可以在该类中访问this在这种情况下,它代表您的x

Validation y = x.clone();

对于“浅拷贝”,前面的示例很好,但对于“深层拷贝”,您需要覆盖默认的Object#clone()行为:< / p>

class A implements Cloneable {

    public @Override A clone() throws CloneNotSupportedException {
        return (A)super.clone(); // or or another implementation
    }

}

class Validation implements Cloneable {

    // an example of a reference-type field
    private A a; // with a setter

    public @Override Validation clone() throws CloneNotSupportedException {
        Validation newClone = new Validation();

        // note that the `A` class has to implement the `Cloneable`
        // and override the `clone` method making it `public`
        newClone.setA(this.a.clone());

        return newClone;
    }

}

*不要忘记实现Cloneable接口以允许克隆。

阅读:Effective Java, Item 11: Override clone judiciously.

答案 1 :(得分:0)

Java api有一个Cloneable接口。Object有一个克隆方法,只有在子类中重写时才能访问它,它也实现了Cloneable接口。您的方法并不真正创建副本,因为“副本”指向原始实例。

假设我复制Validation

Validation v = new Validation();
v.setId(1);
Validation valid = v.copy(v);
valid.setId(2);

现在,v中的ID也会发生变化,因为valid指向v

clone - 方法制作了一份深层复制品。这是一个小例子:

public class Product {

private int id;
private String name;

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@Override
public String toString() {
    return "Product{" + "id=" + id + ", name=" + name + '}';
}

@Override
protected Object clone() throws CloneNotSupportedException {
    Product p = new Product();
    p.setId(id);
    p.setName(name);
    return p;
}   

}

public static void main(String[] args) {
    Product p = new Product();
    try {
        Product clone = (Product) p.clone();
        System.out.println(clone.toString());
    } catch (CloneNotSupportedException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    }
}