수색…


비고

복제는 까다로울 수 있습니다. 특히 오브젝트의 필드가 다른 오브젝트를 보유 할 때. 필드 값 (예 : 다른 오브젝트에 대한 참조) 만 복사하는 대신 전체 복사 를 수행하려는 경우가 있습니다.

결론은 clone이 깨 졌음을 Cloneable , Cloneable 인터페이스를 구현하고 clone 메서드를 재정의하기 전에 두 번 생각해야합니다. clone 방법은에 선언 된 Object 클래스와하지에 Cloneable 하므로, 인터페이스 Cloneable 는 공공 부족하기 때문에 인터페이스로 작동하지 clone 방법을. 결과적으로 clone 사용에 대한 계약이 문서화되고 약하게 시행됩니다. 예를 들어, 우선 클래스 clone 때때로 무시 모든 부모 클래스에 의존 clone . 그들은 강제로 그렇게하지 않으며, 그렇지 않은 경우 코드가 예외를 throw 할 수 있습니다.

복제 기능을 제공하는 훨씬 더 나은 솔루션은 복사 생성자 또는 복사 팩토리 를 제공하는 것입니다. Joshua Bloch의 Effective Java Item 11 : 복제를 현명하게 무시하십시오.

복사 생성자를 사용하여 복제

객체를 복제하는 쉬운 방법은 복사 생성자를 구현하는 것입니다.

public class Sheep {

    private String name;

    private int weight;

    public Sheep(String name, int weight) {
        this.name = name;
        this.weight = weight;
    }

    // copy constructor
    // copies the fields of other into the new object
    public Sheep(Sheep other) {
        this.name = other.name;
        this.weight = other.weight;
    }

}

// create a sheep
Sheep sheep = new Sheep("Dolly", 20);
// clone the sheep
Sheep dolly = new Sheep(sheep); // dolly.name is "Dolly" and dolly.weight is 20

Clonable 인터페이스를 구현하여 복제

Cloneable 인터페이스를 구현하여 객체 복제.

public class Sheep implements Cloneable {

    private String name;

    private int weight;

    public Sheep(String name, int weight) {
        this.name = name;
        this.weight = weight;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

}

// create a sheep
Sheep sheep = new Sheep("Dolly", 20);
// clone the sheep
Sheep dolly =  (Sheep) sheep.clone(); // dolly.name is "Dolly" and dolly.weight is 20

얕은 사본을 수행하는 복제

개체를 복제 할 때 개체의 필드의 얕은 복사본 을 수행하는 것이 기본 동작입니다. 이 경우 원본 개체와 복제 된 개체 모두 동일한 개체에 대한 참조를 보유합니다.

이 예제는 동작을 보여줍니다.

import java.util.List;

public class Sheep implements Cloneable {

    private String name;

    private int weight;

    private List<Sheep> children;

    public Sheep(String name, int weight) {
        this.name = name;
        this.weight = weight;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public List<Sheep> getChildren() {
        return children;
    }

    public void setChildren(List<Sheep> children) {
        this.children = children;
    }

}

import java.util.Arrays;
import java.util.List;

// create a sheep
Sheep sheep = new Sheep("Dolly", 20);

// create children
Sheep child1 = new Sheep("Child1", 4);
Sheep child2 = new Sheep("Child2", 5);

sheep.setChildren(Arrays.asList(child1, child2));

// clone the sheep
Sheep dolly =  (Sheep) sheep.clone();
List<Sheep> sheepChildren = sheep.getChildren();
List<Sheep> dollysChildren = dolly.getChildren();
for (int i = 0; i < sheepChildren.size(); i++) {
    // prints true, both arrays contain the same objects
    System.out.println(sheepChildren.get(i) == dollysChildren.get(i));
}

딥 카피를 수행하는 복제

중첩 된 개체를 복사하려면이 예제와 같이 전체 복사본 을 수행해야합니다.

import java.util.ArrayList;
import java.util.List;

public class Sheep implements Cloneable {

    private String name;

    private int weight;

    private List<Sheep> children;

    public Sheep(String name, int weight) {
        this.name = name;
        this.weight = weight;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        Sheep clone = (Sheep) super.clone();
        if (children != null) {
            // make a deep copy of the children
            List<Sheep> cloneChildren = new ArrayList<>(children.size());
            for (Sheep child : children) {
                cloneChildren.add((Sheep) child.clone());
            }
            clone.setChildren(cloneChildren);
        }
        return clone;
    }

    public List<Sheep> getChildren() {
        return children;
    }

    public void setChildren(List<Sheep> children) {
        this.children = children;
    }

}

import java.util.Arrays;
import java.util.List;

// create a sheep
Sheep sheep = new Sheep("Dolly", 20);

// create children
Sheep child1 = new Sheep("Child1", 4);
Sheep child2 = new Sheep("Child2", 5);

sheep.setChildren(Arrays.asList(child1, child2));

// clone the sheep
Sheep dolly =  (Sheep) sheep.clone();
List<Sheep> sheepChildren = sheep.getChildren();
List<Sheep> dollysChildren = dolly.getChildren();
for (int i = 0; i < sheepChildren.size(); i++) {
    // prints false, both arrays contain copies of the objects inside
    System.out.println(sheepChildren.get(i) == dollysChildren.get(i));
}

복사 팩토리를 사용한 복제

public class Sheep {

    private String name;
    
    private int weight;
    
    public Sheep(String name, int weight) {
        this.name = name;
        this.weight = weight;
    }
    
    public static Sheep newInstance(Sheep other);
        return new Sheep(other.name, other.weight)
    }

}


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow