2016-10-29 1 views
1

Ich versuche, eine Kopiermethode zu erstellen, aber was ich habe, scheint zu einfach und ich denke, es tut im Wesentlichen nichts.Das erste Mal erstellen eine Kopiermethode

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

so umgesetzt, wenn etwa so:

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

Und dann stellen Sie sicher, dass y alle Methoden/Variablen x hat und dass, wenn sie mit den Variablen in y arbeiten, ich haben keinen Einfluss auf die Variablen in x. Ich habe das Gefühl, was ich will ist eine "Deep Copy" -Methode und ich fand einen Beitrag darüber hier: Creating a deep copy method, Java aber diese Person hat kein Argument für ihre Methode, also weiß ich nicht, wie es tatsächlich kopiert.

+0

Ob Sie eine tiefe Kopie benötigen oder nicht, hängt alles vom Code innerhalb der Vlidation-Klasse ab, können Sie Ihren Validierungscode angeben? – developer

+0

Das Beispiel in der Verknüpfung erstellt eine Kopie des aktuellen Objekts ('this'). – infiniteRefactor

+0

Mögliches Duplikat von [Clone() vs Copy-Konstruktor - was in Java empfohlen wird] (http://stackoverflow.com/q/2427883/5221149). – Andreas

Antwort

1

Ja, es tut nichts, außer die gleiche Referenz, die übergeben wurde.

Wahrscheinlich werden Sie nach der Object#clone() * Methode suchen:

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

In 95% der Fälle, ist, dass die am besten geeignete und angemessene Lösung für verschiedene Arten von Aufgaben. Sie sollten das Rad nicht neu erfinden, wenn Sie es nicht brauchen.

Als Java-Dokumentation sagt:

... Diese Methode führt eine "flache Kopie" dieses Objekts, keine "tiefe Kopie" Betrieb.

... es kann notwendig sein, ein oder mehrere Felder des Objekts zu ändern, das von super.clone zurückgegeben wird, bevor es zurückgegeben wird.

Validation y = x.copy(x); 

Sie sollten keine x auf eine copy-Methode übergeben, denn wenn man auf einer x Instanz diese Methode aufrufen, in der Klasse, die Sie einen Zugang zu this haben, die in diesem Fall Ihre x darstellt .

Validation y = x.clone(); 

Für eine "flache Kopie" das obige Beispiel ist gut, aber für eine "tiefe Kopie" Sie benötigen einen Standard Object#clone() Verhalten außer Kraft zu setzen:

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

} 

* Vergessen Sie nicht, die Schnittstelle Cloneable zu implementieren, um das Klonen zu ermöglichen.

zu lesen: Effective Java, Item 11: Override clone judiciously.

+0

Oh okay, also wird dies ein doppeltes Objekt erzeugen, aber deren Variablen haben andere Referenzen als das erste Objekt? – Redcoatwright

+0

@Redcoatwright, Nein, Instanz Feld Referenzen werden die gleichen wie in der Herkunft Objekt – Andrew

+0

@Redcoatwright, ich aktualisiert – Andrew

0

Die Java api eine Cloneable Schnittstelle hat. Object verfügt über eine Klonmethode, auf die nur zugegriffen werden kann, wenn sie in der Unterklasse außer Kraft gesetzt wird und die Cloneable-Schnittstelle ebenfalls implementiert wird. Ihre Methode erstellt keine Kopie, da die "Kopie" auf die ursprüngliche Instanz verweist.

Lassen Sie uns sagen, dass ich eine Kopie von Validation machen:

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

Nun ist die ID in v werden auch, weil valid Punkte zu v ändern.

Aber die clone -Methode macht eine Deep-Kopie. Hier ein kleines Beispiel:

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

Sorry, das könnte ein bisschen über meinen Kopf sein. Was machen die "Würfe"? – Redcoatwright

+1

Es gibt ein schlechtes Beispiel. Ist Ihnen klar, dass eine geklonte Instanz die gleichen Instanzreferenzen haben wird wie ein Ursprung? Für ein primitives "int" -Feld ist es nicht so wichtig wie für einen "String" aufgrund des "String" -Poolings. In diesem Fall hat der Standard 'Object'' clone' das gleiche Verhalten mit einigen Optimierungen. – Andrew

+0

@Redcoatwright, die 'CloneNotSupportedException' ist eine geprüfte Ausnahme, die ausgelöst wird, wenn Ihre Klasse kein Klonen bereitstellt (die' Cloneable'-Schnittstelle wird nicht implementiert) – Andrew

Verwandte Themen