Zoeken…


Opmerkingen

Klonen kan lastig zijn, vooral als de velden van het object andere objecten bevatten. Er zijn situaties waarin u een diepe kopie wilt uitvoeren in plaats van alleen de veldwaarden te kopiëren (dwz verwijzingen naar de andere objecten).

De bottom line is kloon is gebroken , en je moet twee keer nadenken voordat zij wordt Cloneable interface en overschrijven van de clone -methode. De clone wordt gedeclareerd in de klasse Object en niet in de Cloneable interface, dus Cloneable functioneert niet als een interface omdat er geen openbare clone is. Het resultaat is dat het contract voor het gebruik van clone dun is gedocumenteerd en zwak wordt afgedwongen. Een klasse die clone overschrijft, vertrouwt bijvoorbeeld soms op alle bovenliggende klassen die ook clone overschrijven. Ze worden hiertoe niet gedwongen en als ze dat niet doen, kan uw code uitzonderingen veroorzaken.

Een veel betere oplossing voor het bieden van kloonfunctionaliteit is het bieden van een kopieerconstructeur of kopieerfabriek . Raadpleeg Effectief Java- item 11 van Joshua Bloch : oordeelkundig kloon overschrijven.

Klonen met behulp van een copy constructor

Een eenvoudige manier om een object te klonen is door een kopieerconstructor te implementeren.

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

Klonen door Clonable-interface te implementeren

Een object klonen door de Cloneable- interface te implementeren.

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

Klonen met een ondiep exemplaar

Standaardgedrag bij het klonen van een object is het uitvoeren van een ondiepe kopie van de velden van het object. In dat geval bevatten zowel het oorspronkelijke object als het gekloonde object verwijzingen naar dezelfde objecten.

Dit voorbeeld laat dat gedrag zien.

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));
}

Klonen met een diepe kopie

Om geneste objecten te kopiëren, moet een diepe kopie worden uitgevoerd, zoals getoond in dit voorbeeld.

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));
}

Klonen met behulp van een kopieerfabriek

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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow